设计模式之门面模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述门面(Facade)模式的:

  门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。

 

 

 

医院的例子

  现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一 个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系 统的各个类打交道一样,不是一件容易的事情。

  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必须首先划价,然后缴费,才可以到化验部门做化验。化验后再回到门诊室。

  

 

  上图描述的是病人在医院里的体验,图中的方框代表医院。

  解决这种不便的方法便是引进门面模式,医院可以设置一个接待员的位置,由接待员负责代为挂号、划价、缴费、取药等。这个接待员就是门面模式的体现,病人只接触接待员,由接待员与各个部门打交道。



 

  

门面模式的结构

  门面模式没有一个一般化的类图描述,最好的描述方法实际上就是以一个例子说明。

  

 

  由于门面模式的结构图过于抽象,因此把它稍稍具体点。假设子系统内有三个模块,分别是ModuleA、ModuleB和ModuleC,在门面模式中,一般有两个角色:



 

 

  ●  门面(Facade)角色 :客户端可以调用这个角色的方法。此角色知晓相关的(一个或者多个)子系统的功能和责任。在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。

  ●  子系统(SubSystem)角色 :可以同时有一个或者多个子系统。每个子系统都不是一个单独的类,而是一个类的集合(如上面的子系统就是由ModuleA、ModuleB、ModuleC三个类组合而成)。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

源代码

  子系统角色中的类:

 
public class ModuleA {
    //示意方法
    public void testA(){
        System.out.println("调用ModuleA中的testA方法");
    }
}
 
 
public class ModuleB {
    //示意方法
    public void testB(){
        System.out.println("调用ModuleB中的testB方法");
    }
}
 
 
public class ModuleC {
    //示意方法
    public void testC(){
        System.out.println("调用ModuleC中的testC方法");
    }
}
 

  门面角色类:

 
public class Facade {
    //示意方法,满足客户端需要的功能
    public void test(){
        ModuleA a = new ModuleA();
        a.testA();
        ModuleB b = new ModuleB();
        b.testB();
        ModuleC c = new ModuleC();
        c.testC();
    }
}
 

  客户端角色类:

 
public class Client {

    public static void main(String[] args) {
        
        Facade facade = new Facade();
        facade.test();
    }

}
 

  Facade类其实相当于A、B、C模块的外观界面,有了这个Facade类,那么客户端就不需要亲自调用子系统中的A、B、C模块了,也不需 要知道系统内部的实现细节,甚至都不需要知道A、B、C模块的存在,客户端只需要跟Facade类交互就好了,从而更好地实现了客户端和子系统中A、B、 C模块的解耦,让客户端更容易地使用系统。

 


门面模式的实现

  使用门面模式还有一个附带的好处,就是能够有选择性地暴露方法。一个模块中定义的方法可以分成两部分,一部分是给子系统外部使用的,一部分是子 系统内部模块之间相互调用时使用的。有了Facade类,那么用于子系统内部模块之间相互调用的方法就不用暴露给子系统外部了。

  比如,定义如下A、B、C模块。

 
public class Module {
    /**
     * 提供给子系统外部使用的方法
     */
    public void a1(){};
    
    /**
     * 子系统内部模块之间相互调用时使用的方法
     */
    public void a2(){};
    public void a3(){};
}
 
 
public class ModuleB {
    /**
     * 提供给子系统外部使用的方法
     */
    public void b1(){};
    
    /**
     * 子系统内部模块之间相互调用时使用的方法
     */
    public void b2(){};
    public void b3(){};
}
 
 
public class ModuleC {
    /**
     * 提供给子系统外部使用的方法
     */
    public void c1(){};
    
    /**
     * 子系统内部模块之间相互调用时使用的方法
     */
    public void c2(){};
    public void c3(){};
}
 

 

 
public class ModuleFacade {
    
    ModuleA a = new ModuleA();
    ModuleB b = new ModuleB();
    ModuleC c = new ModuleC();
    /**
     * 下面这些是A、B、C模块对子系统外部提供的方法
     */
    public void a1(){
        a.a1();
    }
    public void b1(){
        b.b1();
    }
    public void c1(){
        c.c1();
    }
}
 

 

  这样定义一个ModuleFacade类可以有效地屏蔽内部的细节,免得客户端去调用Module类时,发现一些不需要它知道的方法。比如 a2()和a3()方法就不需要让客户端知道,否则既暴露了内部的细节,又让客户端迷惑。对客户端来说,他可能还要去思考a2()、a3()方法用来干什 么呢?其实a2()和a3()方法是内部模块之间交互的,原本就不是对子系统外部的,所以干脆就不要让客户端知道。

一个系统可以有几个门面类

  在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只有一个门面类,而仅仅 是说对每一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统都有一个门面类,整个系统可以有数个门面类。

为子系统增加新行为

  初学者往往以为通过继承一个门面类便可在子系统中加入新的行为,这是错误的。门面模式的用意是为子系统提供一个集中化和简化的沟通管道,而不能向子系统加入新的行为。比如医院中的接待员并不是医护人员,接待员并不能为病人提供医疗服务。

 

门面模式的优点

  门面模式的优点:

  ●  松散耦合

  门面模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。

  ●  简单易用

  门面模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟门面类交互就可以了。

  ●  更好的划分访问层次

  通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。

      


 

门面模式在Tomcat中的使用

  Tomcat中门面模式使用的很多,因为Tomcat中有很多不同组件,每个组件要相互通信,但是又不能将自己内部数据过多的暴露给其他组件。用门面模式隔离数据是个很好的方法。

  下面是Request上使用的门面模式:

  


 
 

  使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类,并且重写doGet与doPost方法(当然只重写service方法也是可以的)。

复制代码
public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        this.doPost(request, response);
            
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            
        
    }

}
 

  可以看出doGet与doPost方法有两个参数,参数类型是接口HttpServletRequest与接口 HttpServletResponse,那么从Tomcat中传递过来的真实类型到底是什么呢?通过debug会发现,在真正调用 TestServlet类之前,会经过很多Tomcat中的方法。如下图所示



 

  注意红色方框圈中的类,StandardWrapperValue类中的invoke方法225行代码如下:

                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());

  在StandardWrapperValue类中并没有直接将Request对象与Response对象传递给 ApplicationFilterChain类的doFilter方法,传递的是RequestFacade与ResponseFacade对象,为什 么这么说呢,看一下request.getRequest()与response.getResponse()方法就真相大白了。

  Request类

 
    public HttpServletRequest getRequest() {
        if (facade == null) {
            facade = new RequestFacade(this);
        }
        return facade;
    }
 

  Response类

 
    public HttpServletResponse getResponse() {
        if (facade == null) {
            facade = new ResponseFacade(this);
        }
        return (facade);
    }
 

  可以看到它们返回都是各自的一个门面类,那么这样做有什么好处呢?

  Request对象中的很多方法都是内部组件之间相互交互时使用的,比如setComet、setRequestedSessionId等方法 (这里就不一一列举了)。这些方法并不对外部公开,但是又必须设置为public,因为还需要跟内部组件之间交互使用。最好的解决方法就是通过使用一个 Facade类,将与内部组件之间交互使用的方法屏蔽掉,只提供给外部程序感兴趣的方法。

  如果不使用Facade类,直接传递的是Request对象和Response对象,那么熟悉容器内部运作的程序员可以分别把 ServletRequest和ServletResponse对象向下转换为Request和Response,并调用它们的公共方法。比如拥有 Request对象,就可以调用setComet、setRequestedSessionId等方法,这会危害安全性。

 

 

 

 

SAP ALV表格F4搜索帮助不触发DATA_CHANGE?3步排查搞定 本文针对SAP ALV表格中F4搜索帮助选择值后,DATA_CHANGE事件不触发的经典问题,提供了三步系统性排查方法。核心在于理解F4值回写机制,并需在事件处理中手动填充修改表以通知ALV控件数据变更,从而确保后续校验、自动计算等依赖DATA_CHANGE的逻辑能正常执行。 阅读详情

相关推荐

光电振荡器(OEO):从原理到应用,解锁高频微波信号新纪元

本文深入解析了光电振荡器(OEO)的核心原理与前沿应用。OEO通过巧妙的光-电-光转换机制,利用光学谐振腔产生高频、高纯度、低相位噪声的微波信号,有效突破了传统电子电路的频率瓶颈。文章详细拆解了其工作流程,并探讨了在雷达系统、高速光通信及精密测量等领域的硬核应用价值。

weixin_29231027的博客 365

Session Facade模式

SessionFacade模式并不是GOF经典设计模式之一,它是一种EJB Session Bean应用在J2ee架构中的一种相对比较好的实践 。   大家对DAO一定不陌生,我们通常用Dao维护单个对象的持久化。然后再从Dao之上加一个Facade设计模式,即为Service层。这里说的Session Facade模式也和这种模式类似,只是Dao换成了EAO,EAO组件本身就是一种无状

一名系统架构师的征途 4216

流式数据湖存储技术,Apache Paimon是什么?

是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。Paimon 采用开放的数据格式和技术理念,可以与 Apache Flink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。

一个写湿的程序猿 2万+

SaaS系列介绍之十三: SaaS系统体系架构

SaaS系列介绍之十三: SaaS系统体系架构2008-11-13 15:36作者:Yesky 黎宇出处:天极网责任编辑:郑重  1 系统体系架构设计  软件开发中系统体系架构决定了一个系统稳定性、健壮性、可扩展性、兼容性和可用性,它是系统的灵魂。体系架构是架构师所关注的核心。良好的体系架构是系统成功的开端,否则,再好的代码与设计也无济于事。  2 当前.net主要

5565

brpc组件bvar源码解析(一)简介、使用和类的关系

bvar是brpc中的一个重要组件,brpc内部有很多builtin监控都是bvar实现的。 brpc文档介绍bvar“几乎不会给程序增加性能开销,也快于竞争频繁的原子操作”。它的原理是:多线程累加一个计数器时,每个线程只累加私有的变量而不参与全局竞争,因此写时没有锁的竞争;在读取时累加所有线程的私有变量。虽然读比之前慢多了,但写就快多了,因此它使用写多读少的场景,例如统计、监控场景。 1.使用 // bvar::Adder<T>用于累加,下面定义了一个统计read error总数的Adder。

华秋实的专栏 1851

PX4无人机-Gazebo仿真实现动态目标追踪的视觉控制方案

本文详细介绍了PX4无人机在Gazebo仿真环境中实现动态目标追踪的视觉控制方案。从PX4与Gazebo仿真环境搭建、动态目标追踪核心技术栈、仿真环境深度定制技巧到追踪算法的优化实践,提供了全面的技术指导和常见问题排查方法,帮助开发者高效实现无人机视觉追踪功能。

weixin_29196315的博客 450

设计模式之八:外观模式(Facade)

外观模式: 为子系统中的一系列接口提供了一个统一的界面。外观模式定义了一个高层次的接口以使子系统更加easy使用。 Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the ...

aofan9566的博客 134

Python 爬虫进阶技巧:定时爬虫任务实现无人值守采集

常规爬虫多依赖手动触发脚本运行,单次采集完成后需人工二次启动,无法满足日常周期性数据监控、行情抓取、资讯同步、业务台账定时归档等常态化采集需求。搭建可自主调度、自动启停、周期循环的定时爬虫任务,脱离人工干预实现无人值守全自动采集,是爬虫从临时脚本走向工程化落地的关键一步。schedule 轻量定时库官方文档APScheduler 高级定时框架官方文档Python time 内置模块官方文档Linux crontab 定时任务官方手册。

2503_91057718的博客 1117

重学设计模式——你听说过门面模式吗?

前言 在一文了解MVI架构,学起来吧~这篇文章的最后,我们提到了对网域层的理解类似于门面模式,所以这里单独写一篇文章介绍一下门面模式。 再前言 面试的时候,面试官都会问用过什么设计模式,99%程序员的回答都是 单例模式,在多一点就是工厂模式。如果你能说到门面模式相信已经在面试官心中战胜了80%的人。那么什么是门面模式呢? 什么是门面模式 门面模式又叫做外观模式(Facade Design Pattern),是结构型设计模式的一种。我觉得也是设计模式中不管是应用场景还是实现方法最为简单的一种。门

黄林晴 1426

MTEX包在Matlab中实现从EBSD数据生成Abaqus网格与晶粒取向:一种对用户材料旋转矩阵分量实践的全面指南

此教程提供了一种使用MTEX Matlab包处理EBSD数据的方法,并生成Abaqus输入文件,这对于进行多晶体有限元分析具有极大的帮助。但值得注意的是,这只是一个基本的例子,实际应用中可能需要根据您的实际需求进行调整。MTEX包还提供了许多其他的功能,可以进行更复杂的分析和处理,我非常推荐您去探索。希望这篇文章能对您有所帮助,如果您有任何疑问或建议,欢迎留言交流。在接下来的文章中,我将会介绍更多关于MTEX的高级功能,敬请期待。– (完)–

qq_38334677的博客 4437

Android 10.0 SystemUI下拉状态栏点击设置跳转设置时白屏修改

在10.0的系统rom定制化开发中,在SystemUI下拉状态栏下方点击设置图标跳转设置的过程中,发现 有白屏显示挡住设置界面,显示白屏,接下来分析下相关原因来解决这个问题

安卓兼职framework和app工程师的博客 80

门面设计模式

门面模式,也叫外观模式,英文全称是 Facade Design Pattern。门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。门面模式(Facade Pattern)是一种结构型设计模式,它为一组复杂的子系统提供了一个简单的接口,使得子系统更容易使用和理解。在 Java 中,门面模式通常使用一个门面类(Facade Class)来包装一个或多个复杂的子系统,使得客户端只需要和门面类交互,而不需要直接与子系统交互。

学习技术的路上不断沉淀自己 1902

Halcon 形态学 开发案例 (开运算opening(先腐蚀再膨胀)、闭运算closing(先膨胀再腐蚀))

算子方法:功能:使用用户自定义的结构元素对区域进行开运算参数: Region(输入参数) :输入区域 StructElement(输入参数) :结构元素(区域) RegionOpening(输出参数) :开运算后的区域功能:使用圆形结构元素对区域进行开运算参数: Region(输入参数) :输入区域 RegionOpening(输出参数) :开运算后的区域 Radius(输入参数) :圆形结构元素的半径功能:使用矩形结构元素对区域进行开运算。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 1618

设计模式-门面模式

门面模式是一种常用的软件设计模式,也称为外观模式。它提供了一个高层次的接口,将一个子系统的外部与内部通信通过一个统一的对象进行,使得子系统更易于使用。门面模式在系统中主要起中介作用,为复杂的子系统提供一个简单的接口,从而降低了系统的耦合度,提高了系统的灵活性和安全性。

技术人集结地 1772

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

设计模式——门面模式 | 外观模式

定义:要求一个子系统的外部与其内部的通信必须通 过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

m0_66825548的博客 1637

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

设计模式——门面模式(Facade)

要想正确理解设计模式,首先必须明确它是为了解决什么问题而提出来的。 设计模式学习笔记 ——Shulin 转载请注明出处:http://blog.youkuaiyun.com/zhshulin 1、概念         门面模式是对象的结构模式,外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。 2、针对的问题 为子系

在路上 5727

11【门面设计模式】

门面模式(Facade Pattern):也叫外观设计模式,该模式对外有一个统一接口,用来访问子系统中的一群接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。其实我们在写代码时,有意无意的都在大量的使用门面设计模式,但凡高层模块需要调度多个子系统时,我们都会自觉的创建一个新类来封装这些子系统,提供精简的调用方式,让高层模块可以更加容易地间接调用这些子系统的功能;...

緑水長流*z 2533

设计模式之门面模式(Facade Design Pattern)

门面模式也叫外观模式,不管是门面或外观,意思都是提供想让外人看到的部分,隐藏不想被外人看到的部分。从代码角度理解,就是服务提供方通过门面模式来公开对外服务,隐藏内部服务实现的细节。 门面模式的实现可通过两种方法:接口整合和接口隔离。下面我们用伪代码来举例说明: 接口整合例子: 服务提供方有A、B、C三个接口,调用方实现某个功能需要依次调用ABC三个接口。这样的设计增加了调用方调用的成本和调用的复杂度。可以使用门面模式通过接口整合的方法,把ABC三个接口整合成一个门面接口X,调用方只需要调用X接口就可以

xjj1314的专栏 448

设计模式之门面设计模式

一、理清门面 门面模式很简单而且我们就在使用,废话不多说直接上类图。 关注Client类和Facad类还有subsystem即可。 OK,是不是觉得似曾相识,哈哈一会解答。先捋一捋门面的作用,从类图上来看我们外部的Client都需要通过访问Facad类才可以访问到subsystem。 很简单的模式,我不过多做解释了,先码代码。一看就明白了。 二、code 一股脑...

HelloWorld! 660

设计模式之门面模式(C++)

介绍设计模式之门面模式

翟天保的博客 2万+

设计模式—门面模式

哈哈~今天要和在国外读书的同学有约。兴奋之余了解到那个同学读的信息管理都是编程序。瞬间ORZ,顺便YY今天中午吃饭的场景“Leo,借我1000块钱吧?”,“啊,给你凑个整数,给你1024吧”........      好嘞~~段子还是要讲的,知识还是要学的。今天梳理一下门面模式(也称为外观模式 )。 讲这个之前一如既往给出度娘的定义:门面模式,是指提供一个统一的接口去访问多个子系统的多个不同

leo_is_ant的专栏 648

C++设计模式——门面模式(Facade)

定义 门面模式是比较常用的一种设计模式,在 GoF 《设计模式》书中,门面模式是这样定义的: 门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。 门面模式也有的书叫外观模式, 它提供一个高层次的接口,让子系统更易于使用。门面模式用一个门面类来处理子系统的复杂关系,门面类提供简单的Api接口供客户端调用。 高内聚,松耦合。安全。 优点 减少系统的相互依赖 提高了灵活性 提高安全性 适用场景 解决易用性问题。为访问一系列复杂的子系统提供一个统一的、简单的入口,可以使用外观模式;

甜筒八部 的专栏 511

设计模式——门面模式

门面模式 门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。 Facade门面角色:客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没有实际的业务逻辑,只是一个委托类。 subsystem子系统角色 可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,

肥羊汤 380

设计模式之门面模式和调停者模式

文章目录前言一、门面模式Facade1.定义1.案例说明二、调停者模式Mediator1.定义2.案例说明总结 前言 本人对于设计模式的学习,仅供参考! 一、门面模式Facade 1.定义 门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中一组接口提供一个统一的高层结构,使得子系统更容易使用。说的通俗一点就是对功能的封装,使用门面模式就例如:提供一个对外接口A(整体功能),将内部的一些功能(a,b,c)排列好,用户只需要调用这个接口即可。 1.案例说明 二、调停者模式Med

yz1925506412的博客 1077

Python门面设计模式

理解结构设计模式 1、结构型模式描述如何将对象和类组合成更大的结构 2、结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。在面向对象世界中,实体指的是对象或类。 3、类模式可以通过继承来描述抽象,从而提供更有用的程序接口,而对象模式则描述了如何将对象联系起来从而组合成更大的对象。结构型模式是类和对象模式的综合体 下面是结构型设计模式的一些例子: ...

举的博客 386

细说python设计模式之门面模式

文章目录理解结构型设计模式理解门面设计模式现实世界中实现门面模式(示例)最少知识原则迪米特法则(设计准则)问答 前面的单例模式及工厂模式都是属于创建型设计模式,这里要开始讲结构型设计模式—门面模式。 这篇内容: 结构型设计模式概要 利用UML图理解门面设计模式 门面模式与最少知识原则 理解结构型设计模式 结构型模式描述如何将对象和类组合成更大的结构 结构型模式是一种能够简化设计工作的模式,因为它能够找出更简单的方法来认识或表示实体之间的关系。在面向对象世界中,结构型模式是一种能够简化设计工作的模式,因为它能

Apy 506
上一篇: Spring初始化完成后直接执行一个方法,初始化数据(解决方法被重复执行两次的情况)...
下一篇: Google GSON应用 - gson进行日期转换及解析数组
iteye_4921
博客等级 码龄8年 25粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值