设计模式-适配器模式 Java

Java设计模式之<适配器模式>  java的设计模式可分为:创建型模式、结构性模式、行为型模式三类。适配器模式(Adapter Pattern)是一种 结构型设计模式,用于在两个不兼容的接口之间建立桥梁,使它们可以协同工作。它通常用于让已有的类与新接口兼容,而无需修改原有代码。实现方式分为对象适配器(基于组合)、类适配器(基于继承)、接口适配器(基于抽象类)三种。 阅读详情

模式概述

适配器模式(Adapter Pattern)是一种常用的结构型设计模式,它通过转换接口解决不同组件之间的兼容性问题,让原本不兼容的接口能够协同工作。

简单代码示例

场景描述:假设我们需要将第三方支付SDK(仅支持美元支付)集成到支持人民币支付的系统中

1. 类适配器实现(继承方式)

// 目标接口:人民币支付
interface RmbPayment {
    void payInRmb(double amount);
}

// 适配者类:美元支付SDK
class UsdPaymentSdk {
    void payInUsd(double amount) {
        System.out.println("Paid $" + amount + " via USD SDK");
    }
}

// 类适配器(继承)
class PaymentClassAdapter extends UsdPaymentSdk implements RmbPayment {
    private static final double EXCHANGE_RATE = 6.5;

    @Override
    public void payInRmb(double rmbAmount) {
        double usdAmount = rmbAmount / EXCHANGE_RATE;
        super.payInUsd(usdAmount);  // 调用父类方法
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        RmbPayment payment = new PaymentClassAdapter();
        payment.payInRmb(650);  // 支付650人民币
    }
}

2. 对象适配器实现(组合方式)

// 对象适配器(组合)
class PaymentObjectAdapter implements RmbPayment {
    private final UsdPaymentSdk usdPayment;
    private static final double EXCHANGE_RATE = 6.5;

    public PaymentObjectAdapter(UsdPaymentSdk usdPayment) {
        this.usdPayment = usdPayment;
    }

    @Override
    public void payInRmb(double rmbAmount) {
        double usdAmount = rmbAmount / EXCHANGE_RATE;
        usdPayment.payInUsd(usdAmount);  // 委托给被适配对象
    }
}

// 客户端调用
public class Client {
    public static void main(String[] args) {
        UsdPaymentSdk sdk = new UsdPaymentSdk();
        RmbPayment payment = new PaymentObjectAdapter(sdk);
        payment.payInRmb(650);  // 支付650人民币
    }
}

技术细节

1.模式组成

组件职责说明
目标接口客户端期望的接口
适配者类需要被适配的现存组件
适配器转换接口的中间件

2.两种实现方式

  • 类适配器:通过继承实现
  • 对象适配器:通过组合实现

模式应用

Spring MVC中的HandlerAdapter
核心作用:统一处理不同类型的Controller

// 简化版HandlerAdapter接口
public interface HandlerAdapter {
    ModelAndView handle(HttpServletRequest request, 
                       HttpServletResponse response, 
                       Object handler) throws Exception;
}

// 注解控制器适配器
public class AnnotationMethodHandlerAdapter implements HandlerAdapter {
    public ModelAndView handle(HttpServletRequest request,
                              HttpServletResponse response, 
                              Object handler) {
        // 将请求路由到@Controller注解的方法
        // 转换不同参数类型(@RequestParam, @RequestBody等)
    }
}

// 传统Controller适配器
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    public ModelAndView handle(HttpServletRequest request,
                              HttpServletResponse response, 
                              Object handler) {
        ((Controller) handler).handleRequest(request, response);
    }
}
  1. DispatcherServlet获取HandlerMapping返回的Controller
  2. 遍历HandlerAdapter列表,找到支持该Controller类型的适配器
  3. 调用适配器的handle()方法执行请求处理
【Java设计模式】Java设计模式之(十七)适配器模式(Adapter Pattern) 这种类型的设计模式属于结构型模式。 一、适配器模式介绍 1.1 含义 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。 这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。 我们通过下面的实例来演示适配器模式的使用。其中,音频播放器设备只能播放 mp3 文件,通 阅读详情

相关推荐

AUTOSAR AP平台开发避坑指南:基于华为MDC的接口配置与数据通道实战

本文详细解析了AUTOSAR AP平台与华为MDC的协同开发实践,涵盖接口配置、数据通道优化及资源分配策略。通过实战案例展示如何解决传感器接入、通信协议栈优化等常见问题,提升智能驾驶系统性能。特别针对MDC平台特性,提供执行管理、调试调优及安全设计的专业指导,助力开发者高效完成ADAS/AD系统开发。

julia4scientist的博客 1138

Java设计模式—适配器模式(Adapter Pattern)

适配器模式(Adapter Pattern)是一种结构型设计模式;用于将一个类的接口转换成另一个接口,从而满足客户端对接口的需求;在适配器模式中,适配器充当一个中间层,通过实现目标接口并持有原始类的实例来实现对原始类的封装和转换。客户端只需要调用目标接口中定义的方法即可完成对原始类的调用。适配器模式在Java中广泛应用于各种场景,例如,将旧版API适配到新版API、将不同的数据格式适配到统一的数据格式等。所以,适配器模式是个非常非常重要的,是个非常强的设计模式!

是个非常热爱生活、乐观、奋斗、努力的逗比青年 4067

Palantir的本体论建模跟数仓建模的异同

Palantir的Foundry Ontology通过构建组织的数字孪生体,将数据集和模型映射为对象类型、属性、链接和操作类型,形成完整的语义知识网络。与传统数仓建模相比,本体建模以业务问题为驱动,强调细粒度语义和实时决策能力,采用图语义技术实现灵活的映射关系。

轩哥的个人研究和成长记录 1589

Java设计模式 八 适配器模式 (Adapter Pattern)

适配器模式是一种解决。

空 1090

GEOPHYSICS 投稿避坑指南:从格式规范到双盲评审的实战解析

本文详细解析了GEOPHYSICS期刊投稿的全流程避坑指南,从格式规范、数据声明到双盲评审的实战策略。特别强调了数学公式排版、图表制作标准以及投稿系统的隐藏关卡,帮助作者避免常见错误,提升投稿成功率。

weixin_30606461的博客 236

Open3D 点云变换【2025最新版】

点云平移、旋转、缩放、欧式变换的python代码实现。博客长期更新,本文最近更新时间为:2025年1月16日。

点云侠的博客 37万+

adapter pattern java_Java设计模式之适配器模式(Adapter Pattern)

Java设计模式之适配器模式(Adapter Pattern),适配器模式是Java中的结构性模式的一种,最近详细的比较安卓中的Listview和RecycleView的区别,有一点很明显,就是RecycleView中就根本没有添加header和footer的方法,像这种方法也是我们平时常用的,那么只能自己封装了,参考了Listview的做法发现里面用到了适配器的模式就静下心来好好研究了下适配器模...

weixin_39967120的博客 200

点云中概念:匹配、配准、融合

匹配,是寻找与一幅图相似的图像(不对寻找到的图像做矫正)。 配准,是寻找相似图像但是变形后的图像(需要做一些旋转之类的校正变换)。 融合,是多幅图像连接成一幅大图,视频集成中用的比较多。 1)匹配: 2)配准: 比如由于固定式激光雷达受测量方式的限制和被测物体集合形状的限制,固定的话一次只能扫描被测物体有限范围的点云数据(比如一个面??),这需要在多个视角下进行多次扫描(就是将激光雷达前后左右四个面都扫一下??对的),然而每个视角下得到点云数据都具有独立的坐标系,无法直接进行拼接(拼接就是将四个面

m0_37957160的博客 1万+

Java设计模式-适配器模式

适配器模式是一种结构型设计模式,它主要通过将一个类的接口转换成客户端所期望的另一个接口,来解决接口不兼容的问题。适配器模式一般包括三个角色:目标(Target)、适配器(Adapter)和被适配者(Adaptee)。其中,目标角色是客户端所期望的接口,适配器角色是将被适配者的接口转换成目标接口的类,被适配者角色是需要被适配的类。适配器模式与其他设计模式的区别在于,它主要是用于接口转换,而其他模式则主要用于解决其他问题,如工厂模式用于对象创建、单例模式用于对象的唯一性等等。

小薯条的博客 989

实验2 存储器设计与实现【计算机组成原理】

实验2 存储器设计与实现【计算机组成原理】

小心星的博客 2398

[网络安全自学篇] 六.OllyDbg动态分析工具基础用法及Crakeme逆向破解

这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步。上一篇文章分享了IDA Pro反汇编工具的基础用法,并简单讲解一个EXE逆向工程解密实战方法;本篇文章将讲解动态分析OllyDbg工具的基础用法,主要是结合两个Crakeme案例逆向破解。希望对初学者有帮助,大神请飘过,谢谢各位看官!

杨秀璋的专栏 1万+

【Java设计模式】适配器模式

文章目录概述适用场景优点缺点拓展适配器-相关设计模式演示 概述 定义:将一个类的接口转换成客户期望的另一个接口 使原本接口不兼容的类可以一起工作 类型:结构型 适用场景 ◆已经存在的类,它的方法和需求不匹配时(方法结果相同或相似) ◆不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案 优点 能提高类的透明性和复用,现有的类复用但不需要改变...

明月沉江春雾晓 1388

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【JAVA设计模式】之适配器模式(AdapterPattern)

使用场景 复用现有类的功能。 项目并非都是从零开始,而在我们编程过程中,也不是所有的功能都需要重新去写,复用现有类的功能是最直接有效的途径 版本升级与兼容性。 随着版本的迭代升级,旧有的一些功能渐渐无法满足需求,现实中又不能直接摒弃,使用Adapter模式可以轻松的来兼容维护新旧版本 图解适配器模式 ...

兵临城下的博客 286

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

DesignPattern_Java:Adapter Pattern

适配器模式 Adapter Pattern 变压器模式Convert the interface of a class into another interface clients expect.Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.将一个类的接口变换

Anonymous 2342

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java设计模式之适配器模式(Adapter Pattern)

总结: 适配器模式是一种简单而实用的设计模式,它能够解决接口不匹配的问题,使得原本不兼容的类可以一起工作。但是,我们发现MP3音乐的播放接口与MP4音乐的播放接口不同。介绍: 适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。例如,一个类使用的是旧的接口,而我们又想要使用一个新的接口,但两者之间方法的名称和参数不同。在上面的示例中,我们成功地使用了适配器模式,通过适配器将MP3音乐播放器适配成了MP4音乐播放器的接口,实现了MP3和MP4音乐播放器之间的无缝协作。

weixin_38682092的博客 152

adapter pattern java_Java设计模式之适配器模式Adapter Pattern

适配器模式Adapter Pattern类型:结构型模式定义:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。--《JAVA与模式》优点:更好的复用性更好的扩展性缺点:过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。...

weixin_42321940的博客 265

Java设计模式之适配器模式

Java设计模式之适配器模式前言正文一、定义二、分类三、结构四、缺省适配器模式五、双向适配器六、适配器模式优缺点与适用环境优点类适配器模式:对象适配器模式:缺点类适配器模式:对象适配器模式:适用环境 前言 适配器模式是一种使用频率非常高的结构型设计模式,如果系统中存在不兼容的接口,可以通过引入一个适配器来使原本因为接口不兼容而不能在一起工作的两个类能够协同工作。 在GoF设计模式中包含7种结构型模...

js_tengzi的博客 393

图解Java设计模式之适配器模式

图解Java设计模式之适配器模式现实生活中的适配器例子适配器模式基本介绍适配器模式工作原理类适配器模式类适配器模式注意事项和细节对象适配器模式对象适配器模式注意事项和细节接口适配器模式适配器模式在SpringMVC框架应用的源码分析适配器模式的注意事项和细节 现实生活中的适配器例子 泰国插座用的是两孔的(欧标),可以买个多功能转换插头(适配器),这样就可以使用了。 适配器模式基本介绍 1)适配器...

不一样的花朵的博客 519

Java设计模式-适配器模式(Adapter Pattern)

适配器模式作为一种结构型设计模式,在软件系统设计开发中使用到的频率非常之高,比如Java中的jdbc。本文结合具体案例讲解适配器模式的知识要点。

IT熊的专栏 387

Java设计模式-结构型设计模式-适配器模式

Java设计模式- 结构型设计模式-适配器模式

Fatter$hday的博客 1931

java设计模式—适配器模式(Adapter Pattern)

主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式 类的适配器模式 public class DesignPatternTest { @Test public void test1(){ Targetable target = new Adapter(); target.method1(); target.method2(); } } class Source { public void method1()

weixin_43920664的博客 183

java设计模式---适配器模式(Adapter pattern)

java设计模式—适配器模式(Adapter pattern) 前面已经详细的讲解了java23种设计模式中的创建型模式,接下来就讲解下结构型设计模式—适配器模式(Adapter pattern) 1. 定义 适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不兼容而无法一起工作的两个类能一起工作。适配器模式是结构型设计模式之一,其在不修改原来两个模块代码的情况下,将...

渔潭的博客 535

JAVA设计模式之适配器模式

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作

hyzsuccess的博客 894

JAVA设计模式——适配器模式

JAVA设计模式——适配器模式 一.主要概念 1.定义 把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 2.适配器模式涉及的角色 源(Adaptee):需要被适配的对象或类型,相当于插头。 适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。 目标(Target):期待得到的目标,相当于插座。 3.适配器模式实现的三...

a158s168的博客 257
上一篇: Spring定时任务延时触发分析与解决:从单线程阻塞到多线程并发
下一篇: Bug 记录:SecureRandom.getInstanceStrong()导致验证码获取阻塞
刘火锅
博客等级 码龄7年 121粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值