结构型模式:代理模式

3、结构型模式:代理模式 本文详细介绍了代理模式的基本概念、应用场景及实现步骤,并结合C#语言展示了具体的实现细节与优化技巧。文章涵盖认证代理、缓存代理、日志代理等实际案例,同时探讨了代理模式与工厂模式、单例模式的结合使用方式。通过学习本文内容,开发者可以更好地理解和应用代理模式,以提升代码质量与系统灵活性。 阅读详情

什么是代理模式?

代理模式很像我们生活中的"中间人"。想象一下,当你请明星参加活动时,你通常不会直接联系明星本人,而是联系他的经纪人。这个经纪人就是一个"代理",他代表明星处理各种事务,筛选请求,安排日程等。

在编程中,代理模式也是这样工作的:我们创建一个"代理对象",它控制着对另一个"真实对象"的访问。当你想使用真实对象时,你实际上是在和代理对象打交道。

为什么要用代理模式?

思考场景:

  • 你想在访问某个重要文件前检查使用者的权限
  • 你需要延迟加载一个很大的图片,直到真正需要显示它时
  • 你希望记录每次对数据库的访问操作
  • 你要在网络上远程调用另一台计算机上的程序

这些场景都很适合使用代理模式,它可以帮我们:

  1. 控制访问:像保安一样,检查谁能访问对象
  2. 延迟加载:懒惰一点,等真正需要时才创建开销大的对象
  3. 增加功能:在不改变原对象的情况下,添加新功能
  4. 远程访问:让远程对象看起来就像本地对象一样易用

代理模式长什么样?

用一个餐厅点餐的例子来说明。顾客(客户端)不直接告诉厨师(真实对象)做什么菜,而是告诉服务员(代理),服务员再把请求传给厨师。

// 菜单接口
interface FoodService {
    void orderFood(String food);
}

// 厨师(真实对象)
class Chef implements FoodService {
    @Override
    public void orderFood(String food) {
        System.out.println("厨师正在烹饪: " + food);
    }
}

// 服务员(代理对象)
class Waiter implements FoodService {
    private Chef chef = new Chef();
    
    @Override
    public void orderFood(String food) {
        System.out.println("服务员记录订单: " + food);
        
        // 检查库存
        if ("鱼翅".equals(food)) {
            System.out.println("抱歉,鱼翅已售罄");
            return;
        }
        
        // 转发给厨师
        chef.orderFood(food);
        
        System.out.println("服务员准备上菜: " + food);
    }
}

// 顾客使用
class Customer {
    public static void main(String[] args) {
        FoodService waiter = new Waiter();
        waiter.orderFood("宫保鸡丁");
        waiter.orderFood("鱼翅");
    }
}

在这个例子中,Waiter(服务员)就是一个代理,它实现了和Chef(厨师)相同的接口,但在转发请求前后添加了额外的处理。

代理模式有哪些种类?

1. 静态代理:写死在代码里的代理

上面餐厅的例子就是静态代理。代理关系在写代码时就确定了,服务员只能代理厨师。

生活例子:固定的售票窗口只能卖特定线路的车票。

2. 动态代理:灵活多变的代理

不用事先为每个对象写好代理类,而是在程序运行时动态创建代理。

生活例子:万能中介,今天代理房屋出租,明天代理二手车买卖。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {
    private Object target; // 可以是任何对象
    
    public DynamicProxyHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始处理: " + method.getName());
        
        // 调用目标对象的方法
        Object result = method.invoke(target, args);
        
        System.out.println("处理完成: " + method.getName());
        return result;
    }
}

// 动态代理示例
public class DynamicProxyDemo {
    public static void main(String[] args) {
        // 创建真实对象
        Chef chef = new Chef();
        
        // 创建动态代理
        FoodService proxy = (FoodService) Proxy.newProxyInstance(
            FoodService.class.getClassLoader(),
            new Class<?>[] { FoodService.class },
            new DynamicProxyHandler(chef)
        );
        
        // 使用代理
        proxy.orderFood("糖醋排骨");
    }
}

3. 远程代理:远在天边,近在眼前

让远程对象看起来像本地对象一样。

生活例子:你在国内用支付宝付款,但实际上商品在美国,支付宝作为代理处理了跨国支付细节。

4. 保护代理:守门员

控制对敏感对象的访问。

生活例子:保安检查你的门禁卡,确认你有权限才让你进入大楼。

5. 虚拟代理:按需加载

延迟创建开销大的对象,直到真正需要。

生活例子:你打开网页时,图片可能显示一个占位符,然后慢慢加载出来。

class HeavyImage implements Image {
    private String filename;
    
    public HeavyImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }
    
    private void loadFromDisk() {
        System.out.println("加载大图片: " + filename + "(这很慢)");
        // 模拟耗时操作
        try { Thread.sleep(1000); } catch (InterruptedException e) { }
    }
    
    public void display() {
        System.out.println("显示: " + filename);
    }
}

class ImageProxy implements Image {
    private String filename;
    private HeavyImage realImage;
    
    public ImageProxy(String filename) {
        this.filename = filename;
    }
    
    public void display() {
        // 延迟加载,直到真正需要显示时
        if (realImage == null) {
            realImage = new HeavyImage(filename);
        }
        realImage.display();
    }
}

实际生活中的代理模式

明星和经纪人

  • 明星:真实对象
  • 经纪人:代理
  • 粉丝/商家:客户端

经纪人负责筛选邀约、谈判报酬、安排日程,保护明星不被骚扰。

网购和电商平台

  • 生产厂家:真实对象
  • 电商平台:代理
  • 消费者:客户端

淘宝、京东等平台作为代理,负责展示商品、处理支付、物流等。

法律代理

  • 法律:真实对象
  • 律师:代理
  • 当事人:客户端

律师代表当事人处理法律事务,提供专业建议和服务。

实用场景示例:图片加载器

假设我们在开发一个相册应用,需要显示大量高清图片。如果一次性加载所有图片,会很慢且浪费内存。我们可以使用代理模式来延迟加载图片:

interface Image {
    void display();
}

// 真实图片(重量级对象)
class RealImage implements Image {
    private String filename;
    
    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }
    
    private void loadFromDisk() {
        System.out.println("加载图片:" + filename);
        // 模拟耗时的加载过程
        try { Thread.sleep(1000); } catch (InterruptedException e) { }
    }
    
    @Override
    public void display() {
        System.out.println("显示图片:" + filename);
    }
}

// 图片代理
class ProxyImage implements Image {
    private String filename;
    private RealImage realImage;
    
    public ProxyImage(String filename) {
        this.filename = filename;
    }
    
    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

// 相册应用
public class PhotoAlbum {
    public static void main(String[] args) {
        // 创建相册(使用代理)
        Image[] album = new Image[5];
        album[0] = new ProxyImage("高清风景1.jpg");
        album[1] = new ProxyImage("高清风景2.jpg");
        album[2] = new ProxyImage("高清风景3.jpg");
        album[3] = new ProxyImage("高清风景4.jpg");
        album[4] = new ProxyImage("高清风景5.jpg");
        
        // 浏览相册(只有查看的图片才会被加载)
        System.out.println("打开相册...");
        // 用户只查看了第3张图片
        album[2].display();
    }
}

实用场景示例:权限控制

假设我们有一个文件系统,不同用户有不同的访问权限:

// 文件接口
interface File {
    String read();
    void write(String content);
}

// 真实文件
class RealFile implements File {
    private String name;
    private String content;
    
    public RealFile(String name) {
        this.name = name;
        this.content = "这是" + name + "的内容";
    }
    
    @Override
    public String read() {
        System.out.println("读取文件: " + name);
        return content;
    }
    
    @Override
    public void write(String content) {
        System.out.println("写入文件: " + name);
        this.content = content;
    }
}

// 文件访问代理
class FileAccessProxy implements File {
    private RealFile realFile;
    private String user;
    
    public FileAccessProxy(String filename, String user) {
        this.realFile = new RealFile(filename);
        this.user = user;
    }
    
    @Override
    public String read() {
        // 所有用户都可以读取
        return realFile.read();
    }
    
    @Override
    public void write(String content) {
        // 检查写入权限
        if ("admin".equals(user)) {
            realFile.write(content);
        } else {
            System.out.println("权限不足:用户 " + user + " 没有写入权限");
        }
    }
}

// 文件系统
public class FileSystem {
    public static void main(String[] args) {
        // 普通用户访问
        File userFile = new FileAccessProxy("用户数据.txt", "张三");
        System.out.println(userFile.read());  // 允许读取
        userFile.write("尝试修改内容");  // 拒绝写入
        
        System.out.println();
        
        // 管理员访问
        File adminFile = new FileAccessProxy("用户数据.txt", "admin");
        System.out.println(adminFile.read());  // 允许读取
        adminFile.write("管理员修改的内容");  // 允许写入
    }
}

代理模式的优点

  1. 单一职责:真实对象专注核心功能,代理对象负责控制逻辑
  2. 扩展性好:不改变原对象,就能在外部添加功能
  3. 保护真实对象:限制对真实对象的直接访问
  4. 降低系统耦合度:客户端和真实对象不直接交互

代理模式的缺点

  1. 增加复杂度:新增了代理类,系统更复杂
  2. 可能降低性能:因为多了一层调用,特别是动态代理
  3. 可能引入不透明性:客户端不知道是在和代理打交道还是真实对象

代理模式和其他模式的区别

代理模式 vs 装饰器模式

  • 代理模式:控制对象访问
  • 装饰器模式:扩展对象功能

区别在于意图:门卫(代理)决定是否让你进入,而化妆师(装饰器)则是让你看起来更漂亮。

代理模式 vs 适配器模式

  • 代理模式:接口相同,加入控制
  • 适配器模式:转换不兼容的接口

区别在于:翻译(适配器)帮你和说不同语言的人交流,而律师(代理)则是以你的名义和法官交流。

什么时候用代理模式?

当你遇到这些情况时,考虑使用代理模式:

  1. 需要控制对某个对象的访问
  2. 需要在不修改已有代码的情况下添加功能
  3. 对象创建成本高,需要延迟初始化
  4. 需要在远程操作中隐藏复杂性
  5. 需要统一处理对多个对象的访问(如缓存、日志)

如何在实际项目中应用代理模式?

  1. 确定真实对象:明确需要被代理的对象
  2. 设计公共接口:代理和真实对象需要实现相同的接口
  3. 实现代理类:基于需求添加额外功能
  4. 选择代理类型:静态代理简单直接,动态代理更灵活
  5. 考虑性能影响:避免在性能关键路径上使用过于复杂的代理

总结

代理模式就像生活中的"中间人",它站在客户和真实对象之间,控制和扩展对真实对象的访问。无论是权限控制、延迟加载,还是增加额外功能,代理模式都能优雅地解决这些问题。

关键是理解代理模式的核心思想:通过引入一个新的对象来控制对原对象的访问。一旦掌握了这个思想,你就能在各种情景中灵活运用代理模式,让你的代码更加健壮和易于扩展。

【低照度图像增强系列】使用MSRCR(Multi-Scale Retinex with Color Restoration)算法对低照度图像进行增强处理 阅读详情

相关推荐

Vivado工程芯片型号更换全流程:从IP更新到生成新bit文件(避坑指南)

本文详细介绍了Vivado工程中更换芯片型号的全流程,包括IP更新、约束文件适配和生成新bit文件的关键步骤。特别针对FPGA开发中常见的兼容性问题提供避坑指南,帮助开发者高效完成芯片迁移,确保设计稳定性和性能优化。

weixin_42549451的博客 298

设计模式之结构型:代理模式

适配器模式是一种​​结构型设计模式​​,用于解决两个不兼容接口之间的兼容性问题。它通过​​包装对象​​的方式,将已有接口转换为客户端期望的接口,类似电源适配器的功能。

keep simple 1098

folium离线地图实战:从下载到部署的完整指南

本文提供了一份完整的folium离线地图实战指南。针对网络不稳定或内网环境下的地图应用需求,详细讲解了如何下载离线地图瓦片数据,并通过两种核心方法(直接替换URL与创建TileLayer)将其集成到folium中。文章还涵盖了部署优化、边界处理及资源本地化等关键步骤,帮助你构建完全脱离网络依赖的交互式地图应用。

weixin_29061041的博客 274

Java设计模式之结构型:代理模式

代理模式的设计动机是通过代理对象来访问真实对象,通过建立一个对象代理类,由代理对象控制原对象的引用,从而实现对真实对象的操作。在代理模式中,代理对象主要起到一个中介的作用,用于协调与连接调用者(即客户端)和被调用者(即目标对象),在一定程度上降低了系统的耦合度,同时也保护了目标对象。但缺点是在调用者与被调用者之间增加了代理对象,可能会造成请求的处理速度变慢,

张维鹏的博客 1万+

告别纯代码:用Visual Studio为LabVIEW封装一个‘即插即用’的海康VisionMaster控件

本文介绍如何利用Visual Studio为LabVIEW封装一个‘即插即用’的海康VisionMaster控件,解决传统集成方式中的代码臃肿和维护困难问题。通过.NET控件封装核心功能,实现LabVIEW与VisionMaster的高效对接,显著提升工业自动化开发效率。

weixin_33744854的博客 505

基于OkHttp3+Retrofit2+RxJava3搭建响应式网络框架

本文介绍了一个基于OkHttp3+Retrofit3+RxJava3的响应式网络框架设计。该框架采用分层架构,OkHttp3负责底层网络请求,Retrofit3封装HTTP接口,RxJava3实现响应式流处理。核心亮点包括:1)高度解耦的分层设计;2)统一的异常处理和响应体封装;3)RxJava3实现线程切换和请求管理;4)MVVM架构适配,业务层只需关注数据逻辑。框架提供了完整的实现方案,包括全局配置、拦截器、响应转换、接口声明、仓库封装等组件,并支持生产环境扩展功能如Cookie持久化、Token刷新等

fuge2008的博客 871

结构型设计模式:看了它,代理模式其实也没那么难

摘要:代理模式是一种结构型设计模式,通过引入代理对象间接访问目标对象,控制或扩展其功能。代理模式包含三个角色:抽象主题类定义接口,代理类控制访问并扩展功能,真实主题类实现具体业务。实现方式分为静态代理(需实现相同接口,冗余但易扩展)和动态代理(运行时生成,灵活高效)。JDK动态代理利用Proxy和InvocationHandler动态生成代理类字节码,相比静态代理更易维护。该模式适用于远程访问、延迟加载、权限控制等场景,是解耦客户端与目标对象的重要设计模式。

weixin_47088026的博客 1072

【PMP认证考试之个人总结】第 4 章 项目范围管理

第 4 章 项目范围管理 4.1 综述   1.产品范围和项目范围的区别 ①产品范围:某项产品、服务或成果所具有的特性和功能; ②项目范围:为交付具有规定特性与功能的产品、服务或成果而必须完成的工作; 2.收集需求、定义范围和创建WBS输出的区别 ①收集需求 ===> 需求跟踪矩阵; ②定义范围 ===> 项目范围说明书;

qq296398300的博客 2892

设计模式-结构型模式:代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,其目的是在不改变原有代码的情况下,为其他对象提供一个代理,以控制对原有对象的访问。

逐梦苍穹的博客 779

华为OD机试_2025 B卷_模拟消息队列(Python,100分)(附详细解题思路)

时间排序:确保事件处理顺序正确消费者管理:集合操作高效维护状态优先级实现:利用消费者ID自然排序边界处理:正确处理空消费者情况。

测试工程师的成长之路 1119

人工智能 (Artificial Intelligence, AI) 原理与代码实例讲解

人工智能 (AI) 机器学习 (Machine Learning) 深度学习 (Deep Learning) 算法 模型 代码实例 应用场景 1. 背景介绍 人工智能 (Artificial Intelligence, AI) 作为一项前沿科技,近年来发展迅速,已渗透到生活的方方面面

AI架构师小马 1227

常用结构型:代理模式

这里就可以运用代理模式,在打开文档时,并不打开图形对象,而是打开图形对象的代理以替代真实的图形。通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。在真实对象创建成功之前虚拟代理 扮演真实对象的替身,而当 真实对象创建之后,虚拟代理将用户的请求转发给真实对象。代理模式指代理控制对其他对象的访问,也就是代理对象控制对原对象的引⽤。

zxf347085420的博客 1397

node: /lib64/libstdc++.so.6: version `CXXABI_1.3.11‘ not found (required by node) 解决方案

本文主要介绍了node: /lib64/libstdc++.so.6: version `CXXABI_1.3.11’ not found (required by node) ,希望能对使用nodejs的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

初探Java设计模式2:结构型模式(代理模式,适配器模式等)

结构型模式 前面创建型模式介绍了创建对象的一些设计模式,这节介绍的结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展。 代理模式 第一个要介绍的代理模式是最常使用的模式...

ctupngu67368的博客 117

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

结构型模式对比:享元模式 vs 代理模式

在软件开发中,资源管理与性能优化是设计的重要考量。为了减少对象创建的开销,控制对象的访问,可以使用享元模式(Flyweight Pattern)和代理模式(Proxy Pattern)来优化对象管理。这两种模式都属于结构型设计模式(Structural Design Patterns),但它们的目的、对象管理方式、适用场景都不同。本文将从性能优化与资源共享、对象实例化控制方式等方面进行对比,帮助你理解它们的区别,并在实际开发中选择合适的模式。

884

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

结构型:代理模式

在不直接操作原始对象的情况下,通过代理对象间接实现功能扩展或访问控制

xike1024的博客 1274

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

结构型模式之代理模式:控制访问的智能方式

在软件开发中,有时我们需要对某个对象的访问进行控制,比如延迟加载、访问控制、性能监控等。代理模式(Proxy Pattern)正是为了解决这一问题而存在的。代理模式是一种结构型设计模式,它为某个对象提供一个代理对象,控制对该对象的访问,从而达到控制对象的行为或对其功能进行扩展的目的。本文将详细讲解代理模式的概念、类型、应用场景、优缺点,并提供Java代码示例,帮助大家理解如何在实际开发中使用代理模式。代理模式的核心思想是通过一个代理对象来控制对目标对象的访问。代理对象和目标对象实现相同的接口或继承自相同的类

萌萌白白的博客 1175

【设计模式】结构型模式(二):代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它允许你提供一个代理对象来控制对某个对象的访问。代理对象可以执行一些额外的操作,如 权限检查、日志记录、延迟初始化 等,然后再将请求转发给实际的对象。

Data · Model · Agent · Repeat 1283

设计模式(三):结构型模式之代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式和组合模式

设计模式之结构型模式 一、概述 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下7种: 代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。 适配器(Adapter)模式:将一个类的接

HX_2021 717

C# 设计模式(结构型模式):代理模式

代理模式是一种结构型设计模式,主要用于为其他对象提供一种代理以控制对该对象的访问。代理对象通常与真实对象具有相同的接口,客户端通过代理对象来间接访问真实对象。代理模式可以分为几种类型:虚拟代理、远程代理、保护代理等,每种类型的代理对象都有不同的应用场景。代理模式是一个强大的设计模式,特别适用于控制对象的访问、延迟加载、权限检查等场景。通过代理类,我们可以在不修改真实对象的情况下,为其添加额外的功能,从而增强系统的灵活性和可维护性。在处理远程调用、缓存和访问控制等问题时,代理模式能够提供非常有效的解决方案。

玉面小浪君的博客 1168

设计模式:结构型-代理模式

目录第一章 代理模式介绍第二章 代理模式实现(静态代理)2.1、抽象主题类2.2、真实主题类2.3、代理类2.4、测试类第三章 代理模式实现(JDK动态代理)3.1、抽象主题类3.2、真实主题类3.3、代理类3.4、测试类第四章 代理模式实现(CGLIB动态代理)4.1、抽象主题类4.2、真实主题类4.3、代理类4.4、测试类第五章 代理模式应用 项目地址:https://gitee.com/caochenlei/design-pattern 第一章 代理模式介绍 代理模式的介绍: 在有些情况下,一个

轻松的小希 912

设计模式系列(15):结构型模式 - 代理模式(Proxy)

另一个对象提供代理或占位符,以控制对它的访问。用于在访问对象时引入一定的间接性,实现额外的控制功能。

1178

模式总结之结构型:代理模式 Vs 适配器模式 Vs 门面模式(外观模式)

三哥们都是结构型模式,长得又有点像,为了深刻区分,写文祭奠一下。 先上UML图 代理模式: 适配器模式: 门面模式(外观模式): 打了例子……呃……举个比方 代理模式: 水浒街,西门庆看上潘金莲,想和她嘿咻嘿咻,但是自己有不能去找潘金莲去说,于是他找到了金牌代理人王婆,王婆就去找潘金莲,经过一番商谈,潘金莲终于答应了西门庆的请求。  适配器模式: 水浒街,西门庆看上潘金莲

jeff技术博客 2067

【c++设计模式15】结构型7:代理模式(Proxy Pattern)

代理模式(Proxy Pattern)是一种结构型设计模式,它提供了一个代理类来控制对于原始对象的访问。代理类和原始类实现相同的接口,客户端通过代理类间接地访问原始对象,从而可以在不改变原始对象的情况下,通过扩展代理类来添加额外的功能或控制访问。

junxuezheng的博客 1137

C++设计模式之结构型模式:代理模式(Proxy)

代理模式是一种结构型设计模式,通过代理对象控制对真实对象的访问,在不修改原对象的情况下实现功能增强(如权限控制、延迟加载、日志记录等)。核心角色包括抽象主题、真实主题和代理,三者实现相同接口确保透明替换。典型应用场景包括图片延迟加载、远程服务调用和访问控制等。相比装饰器模式(功能扩展),代理更强调访问控制,能有效优化性能并保护敏感资源。该模式符合开闭原则,是解耦客户端与真实对象的有效手段。

bkspiderx的博客 1250
上一篇: 【码道】环境搭建:JDK安装与配置
下一篇: 【码道】第一个程序:Hello World解析
Luck_ff0810
博客等级 码龄4年 624粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luck_ff0810

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值