最近在找实习,之前在某场失败的面试的时候,面试官表示我工程思维严重不足,那么什么是工程思维呢…真是费解啊

所以看了看知乎推荐的《研磨设计模式》这个书,这个书读起来还是比较顺畅的,可能因为内容关系,读起来很容易产生”我已经完全理解啦”的错觉。

虽然刚刚做完入职体检,还不知道能不能入职,还是希望自己实习生活顺利吧…有空的话把找实习的过程也写一写吧…

 

设计模式的组成

    • 模式名称

    • 环境和问题

    • 解决方案

    • 效果

    

设计模式的分类

    • 创建型

    • 结构型

    • 行为型

 

简单工厂模式

    接口->对行为的封装

    优先选用接口

    定义子类行为,又要为子类提供公共功能时应该选择抽象类

    Java程序设计

        ○ 表现层

        ○ 逻辑层

        ○ 数据层

    问题:

        Api api = new Impl()

        此时知道了接口的具体实现为Impl,没有实现隔离。

    定义:

        提供一个创建对象实例的功能,无需关心具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类

    方法:

        增加一个Factory类,来通过参数创建类。

    关键:

        Factory和Api是对外的,其余都不对外?

    反射和配置文件来实现新的添加类

    优点:

        ○ 帮助封装

        ○ 解耦

    缺点:

        ○ 增加客户端复杂度

        ○ 不方便扩展子工厂

 

外观模式

    相当于组装电脑直接和装机公司打交道

    问题:

        比如生成代码工具,客户端为了使用生成代码的功能,需要与生成代码子系统内部多个模块交互。

    方法:

        增加一个Facade类

    包装子系统的功能,成为子系统对外的接口

    可以被许多客户端调用,实现复用

    不用和多个模块交互

    一般不进行逻辑的处理

    优点:

        ○ 松散耦合

        ○ 简单易用

        ○ 更好地划分访问的层次

    缺点:

        ○ 也容易让人迷惑

    最少知识原则

    

适配器模式(Adapter)

    更换硬盘的时候,通过转接线来适配不同的设备

    问题:

        同时支持修改数据库和文件读写的日志

    解决:

        增加适配器

    进行转换匹配,复用已有功能

    类别:

        对象适配器

        类适配器:多重继承

            Java中先继承一个对象,再继承一个接口?

    优点:

        ○ 更好的复用性

        ○ 更好的可扩展性

    缺点:

        ○ 容易凌乱

    转换匹配,复用功能

    

单例模式(Singleton)

    问题:

        在一个系统运行期间,某个类只需要一个类实例,应该怎样实现?

    定义:

        保证一个类只有一个实例,并提供一个访问它的全局访问点

    解决:

        类自身来控制构造方法(私有化),并提供getInstance方法。

    类别:

        ○ 懒汉式

        装载对象时不创建,在调用时创建

        延迟加载的思想

        缓存的思想

        线程不安全,需要在getInstance前加上synchronized关键字

        或者加上volatile关键字,将不会被本地线程缓存,直接操作共享内存(不建议大量使用,会屏蔽到虚拟机中的一些必要的代码优化)

        ○ 饿汉式

        装载对象时就创建对象

        线程安全

    巧妙的方法:

        静态内部类,只有在第一次被使用时才会被装载。可以将instance放到静态内部类中,自动线程安全,而且可以延迟加载。

    现在公认的最佳方法是用枚举实现。

    

工厂方法模式(Factory Method)

    框架:

        定义:

            能完成一定功能的半成品软件

        功能:

            § 能完成一定功能,加快应用开发进度

            § 精良的程序架构

        与设计模式对比:

            § 设计模式更加抽象

            § 设计模式是更小的体系结构元素

            § 框架比设计模式更加特例化

    问题:

        实现功能只知道接口,不知道具体实例对象(类似简单工厂的问题???)

    定义:

        定义一个用于创建对象的接口,让子类决定实例化哪个类,Factory Method使一个类的实例化延迟到子类?

    解决:

        搞一个抽象类的抽象方法,然后用多态来解决??

    分类:

        ○ 客户端使用Creator对象

        ○ 客户端使用Creator创建出来的对象

    IoC/DI:

        IoC:控制反转

        DI:依赖注入

        参与者都有谁:

            § 某个对象

            § IoC/DI的容器

            § 某个对象的外部资源

        谁依赖谁:

            某个对象依赖于I/D容器

        为什么需要依赖:

            某个对象需要I/D提供外部资源

        谁注入谁:

            I/D容器注入某个对象

        注入内容:

            注入外部资源

        谁控制谁:

            I/D控制对象

        为何叫翻转:

            主动获取资源变成反向获得资源

        样例:

            setter?工厂模式?

    平行的类层次结构:

        定义:

            两个类层次结构,其中一个类层次中的每个类都在另一个类层次中有一个对应的类的结构,就被称为平行的类层次结构

        体现在工厂模式中

    参数化工厂模式:

        更像简单工厂了?

    优点:

        ○ 可以在不知道具体实现的情况下编程

        ○ 更容易扩展新版本(钩子方法???)

        ○ 连接平行的类层次

    缺点:

        ○ 具体产品对象与工厂方法耦合

    本质:

        延迟到子类来选择实现

    依赖倒置原则:

        依赖抽象,不要依赖具体类

    

抽象工厂模式(Abstract Factory)

    场景:

        组装电脑,自己规定配件,找装机工程师来组装

    问题:

        难以知道CPU和主板是否互相匹配

    定义:

        提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类?

        既要在不知道具体实现的情况下,创建接口的对象,还要约束他们之间的关系

    解决:

        定义抽象工厂,不同子类进行不同组件的装配,通过不同子类来进行限制

    功能:

        产品簇、不同的装机方案限制

    AbstractFactory通常实现成接口

    可以理解为用工厂方法来定义工厂???

    增加参数可以方便扩展,但是不太类型安全?

    抽象工厂模式和DAO:

        DAO:

            数据访问对象

            J2EE的一个标准模式

            抽象和封装所有对数据的访问

        实现:

            抽象工厂

    优点:

        ○ 分离接口和实现

        ○ 使得切换产品簇变得容易

    缺点:

        ○ 不太容易扩展新的产品

        ○ 容易造成类层次复杂

    本质:选择不同产品簇的实现

    可以和单例模式组合使用

 

生成器模式(Builder)

    场景:

        把信息输出到XML或者文本格式

    问题:

        处理过程可以复用,具体实现不同而已

    定义:

        将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

    解决:

        将构建过程抽象出来,然后将具体的过程传入指导者中

    更为重要的部分:

        只要配置不同的生成器,同样的构建过程,就更构建出不同的产品

        ○ 部件构造和产品装配

        ○ 整体构建的算法

    在实现Builder时,只有创建对象的功能,没有组装的功能,Builder接口与抽象工厂类似

    生成复杂对象:

        内部类,私有化构造函数

    优点:

        ○ 松散耦合

        ○ 轻松改变产品的内部表示

        ○ 复用性更好

    本质:分离整体构建算法和部件构造

    与工厂方法组合使用:

        通过工厂方法获取对象,然后进行装配

    与抽象工厂组合使用:

        通过一个复杂的产品簇来构建一个复杂的对象

    

原型模式(Prototype):

    场景:

        订单处理系统,超过1000就拆,直到小于1000

    问题:

        这个操作不应该依赖于订单的具体类型,但是实际上还是会依赖订单的具体类型

    定义:

        用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象

    解决:

        声明一个克隆自身的接口

    功能:

        ○ 通过克隆创建新的对象实例

        ○ 为克隆出来的新的对象复制原有的属性

    浅克隆:只克隆按值传递的数据

    深克隆:引用类型的也会被克隆

    优点:

        ○ 对客户端隐藏具体的实现类型

        ○ 在运行时动态改变具体的实现类型

    本质:

        克隆生成对象

    

中介者模式(Mediator)

    主板的作用

    场景:

        光驱与CPU通过主板来交互

    问题:

        降低耦合

    定义:

        用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显式地相互引用,从而使其耦合松散,可以独立改变交互

    功能:

        封装对象之间的交互,麻烦都给中介者

    中介者可以是单例

    可以通过创建、获取或者从参数中传入需要的同事数据

    优点:

        ○ 松散耦合

        ○ 集中控制交互

        ○ 多对多变成一对多

    缺点:

        ○ 过度集中化

            § 可能会使得中介者过于复杂

    本质:

        封装交互

    

代理模式(Proxy)

    场景:

        一次性访问多条数据

    问题:

        显示数据的所有内容,内存消耗过大了

    定义:

        为其他对象提供一种代理以控制这个对象的访问

    Proxy代理对象:

        实现与具体的目标对象一样的接口,保存一个指向具体目标对象的引用,可以控制对具体目标对象的访问

    Subject目标接口

    RealSubject具体的目标对象

    时间换空间,适用场景为大多数情况用默认代理,小部分情况reload

    功能:

        客户端操作代理,代理操作真正的对象

    分类:

        ○ 虚代理

            § 根据需要来创建开销很大的对象,该对象只有在需要的时候才会被真正创建

        ○ 远程代理

            § 用来在不同地址空间代表同一个对象???

        ○ Copy-on-write代理

            § 虚拷贝

        ○ 保护代理

            § 控制不同的访问权限

        ○ Cache代理

            § 为昂贵的结果提供临时的存储空间,使多个客户端可以共享结果

        ○ 防火墙代理

            § 保护对象不被恶意用户访问和操作

        ○ 同步代理

            § 多个用户访问没有冲突

        ○ 智能指引

            § 访问对象时执行一些附加操作,比如对指向实际对象的引用计数等

    自己实现的->静态代理

    Java.lang.reflect下面的Proxy和InvocationHandler->动态代理

    AOP(面向方面编程)

    本质:

        控制对象访问

    继承也可以实现代理模式

    • 需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理

    • 需要按照需要创建开销很大的对象的时候,可以使用虚代理

    • 需要控制对原始对象的访问的时候,可以用保护代理

    • 需要在访问对象执行一些附加操作的时候,可以使用智能指引代理

 

观察者模式(Observer)

    场景:

        订阅报纸的过程

    问题:

        当一个对象的状态发生改变的时候,如何让依赖于它的所有对象都得到通知

    定义:

        定义对象间一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

    观察者:订阅者

    目标:观察者观察的对象

    增加Subject和Observer等接口

    单向依赖

    推模型和拉模型

        ○ 推模型

            § 目标对象主动向观察者推送目标的详细信息

            § 知道观察者需要什么信息

            § 难以复用

        ○ 拉模型

            § 目标对象再通知观察者时,只传递少量信息,具体信息需要观察者主动到目标对象中获取

    Java.util.Observable系统自带的观察者

    优点:

        ○ 抽象耦合

        ○ 动态联动

        ○ 广播通信

    缺点:

        ○ 无谓的操作

    本质:

        触发联动

 

命令模式(Command)

    场景:

        开机实现调用BIOS、检测设备等功能

    问题:

        客户端想要发出命令或者请求,不关心请求的真正接受者,也不关心具体实现,同一个动作可以有不同内容,处理的具体功能也不同

    定义:

        将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求或记录请求日志,以及支持可撤销的操作

    关键:

        请求封装成对象

    参数化配置

    撤销操作分类:

        ○ 补偿式

        ○ 存储恢复式

    宏命令:

        包含多个命令的命令

    队列请求:

        对命令对象进行排队,组成工作序列,依次取出命令对象来执行。多个线程同时处理一个队列请求。

    日志请求:

        ○ 序列化方法

        ○ 添加存储和装载的方法

    优点:

        ○ 更松散的耦合

        ○ 更动态的控制

        ○ 自然的复合命令

        ○ 更好的扩展性

    本质:

        封装请求

    命令模式可以实现Java的回调机制

    

迭代器模式(Iterator):

    场景:

        整合工资表数据

        两个结构不同的工资表整合起来

    定义:

        提供一种方法顺序访问一个聚合对象中的各个元素,而又不需暴露该对象的内部表示

    关键思想:

        把对聚合对象的遍历和访问从聚合对象中分离出来,放入单独的迭代器中

    分类:

        ○ 内部迭代器

        ○ 外部迭代器

    优点:

        ○ 更好的封装性

        ○ 迭代器模式可以访问聚合对象的内容,无须暴露该聚合对象的内部表示

        ○ 可以用不同的遍历方式遍历同一个聚合

        ○ 聚合对象的内容和具体的迭代算法分离

        ○ 简化了聚合的接口

        ○ 简化客户端调用

        ○ 不同的聚合有统一的遍历方式

        ○ 每个迭代器保持自己的遍历状态

    本质:

        控制访问聚合对象中的元素

    场景:

        ○ 希望提供访问一个聚合对象的内容,不想暴露内部表示

        ○ 希望有多重遍历模式可以访问聚合对象

        ○ 希望为遍历不同的聚合对象提供一个统一的接口

    

组合模式(Composite):

    场景:

        输出商品类别树

    问题:

        不想区分容器对象和叶子对象

    定义:

        将对象组合成树形结构以表示”部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性

    透明性与安全性的对立

    父组件引用

    环状判断(复杂度好垃圾啊….)

    优点:

        ○ 定义了包含基本对象和组合对象的类层次结构

        ○ 统一了组合对象和叶子对象

        ○ 简化了客户端调用

        ○ 更容易扩展

    缺点:

        ○ 很难限制组合中的组件类型

    本质:

        统一叶子对象和组合对象

    

模板方法模式(Template Method):

    场景:

        工作人员和用户不同的登录与验证方式

    问题:

        ○ 重复或相似代码太多

        ○ 扩展起来很不方便

    定义:

        定义一个操作中算法的骨架,从而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

    功能:

        固定算法骨架,从而让具体算法实现可扩展

    抽象类与接口:

        抽象类中可以有具体的实现方法,接口没有

        既要约束子类的行为,又要为子类提供公共功能

    模板的写法:

        模板方法:定义算法骨架的方法

        具体操作:在模板中直接实现

        具体的抽象类操作:实现某些辅助的公共功能

        原语操作:在模板中定义的抽象操作

        钩子操作:提供默认实现可以扩展

        工厂方法:获得实例(参见工厂模式)

    Java回调:

        通过委托来组合功能,耦合强度比继承低

    模板方法两种实现的对比:

        继承,编译期间静态决定,类级关系

        回调,运行期间动态决定,对象级关系

        回调更加灵活,因为Java单继承

        继承更加简单

    Collections的sort是归并排序(震惊)

    优点:

        代码复用

    缺点:

        算法骨架不容易升级

    本质:

        固定算法骨架

    使用场景:

        固定算法骨架

        各个子类中具有公共行为

        控制子类扩展的情况

    

策略模式(Strategy):

    场景:

        面对不同的客户需求,需要报不同的价格

    问题:

        价格类包含了所有的算法,十分复杂

        不同的时候,要使用不同的计算方式

    定义:

        定义一系列的算法,把它们封装起来,并且使它们可以互相替换

    功能:

        把具体的算法实现从具体的业务处理中独立出来,实现成单独的算法类,从而形成一系列的算法,可以使算法互相替换

    上下文与策略模式:

        通过上下文来传入不同的参数,策略可以加入上下文

        两种扩展:

            § 扩展上下文的方式

            § 在策略算法的实现上添加自己需要的数据的方式

    容错恢复机制:

        两种策略:

            § 日志记录到数据库

            § 日志记录到文件

    策略模式与模板方式结合:

        ○ 上下文中实现公共功能,让所有具体的策略算法回调这些方法

        ○ 策略的接口改为接口类,然后在其中实现具体算法的公共功能

        ○ 定义个抽象的父类,让这个父类去实现策略的接口,然后在父类中实现公共的功能

    优点:

        ○ 定义一系列算法

        ○ 避免多重条件语句

        ○ 更好的扩展性

    缺点:

        ○ 客户必须了解每种策略的不同

        ○ 增加了对象数目

        ○ 只适合扁平的算法结构

    本质:

        分离算法,选择实现

    使用场景:

        ○ 出现有许多相关的类,仅仅行为有差别

        ○ 出现同一个算法,有很多不同实现

        ○ 需要封装算法中,有与算法相关数据

        ○ 抽象一个定义了很多行为的类,通过if-else来选择

    

状态模式(State):

    场景:

        在线投票系统

    问题:

        vote方法太大

    定义:

        允许一个对象在其内部状态改变时改变它的行为。

    功能:

        分离状态的行为,通过维护状态的变化,来调动不同状态对应的不同功能

        状态决定行为

    状态对象多采用延迟加载和缓存合用的方式,当第一次需要使用状态对象时候创建,使用完将对象缓存起来,等待下一次使用,缓存框架销毁状态对象

    可以在状态的处理类中处理状态

    数据库中的状态储存

    模拟工作流

    优点:

        ○ 简化应用逻辑控制

        ○ 更好地分离状态和行为

        ○ 更好的扩展性

        ○ 显式化进行状态转换

    缺点:

        ○ 状态类太多,程序杂乱

    本质:

        根据状态来分离和选择行为

    使用场景:

        ○ 行为取决于状态,运行时刻根据状态来改变它的行为

        ○ 一个操作中含有庞大的多分支语句,这些分支依赖于该对象的状态

    

备忘录模式(Memento)

    场景:

        仿真系统模拟多个方案

    问题:

        模拟流程的对象被迫把内部数据结构开放,暴露了对象的实现细节,破坏了对象的封装性

    定义:

        在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

        引入一个存储状态的备忘录对象,为了让外部无法访问这个对象的值,一般把这个对象实现成为需要保存数据的对象的内部类

    功能:

        不破坏封装性的前提下,捕获内部状态

    备忘录对象:

        一般作为原发器对象的内部类来实现,而且是私有的

    原发器对象:

        需要被保存状态或者恢复状态的对象

    管理器对象:

        负责保存备忘录对象(感觉没什么用?)

        管理很多不同的备忘录对象

        存取备忘录对象,不能访问备忘录对象内部的数据

    窄接口:

        窄接口没有任何的方法,只是一个类型标识,使得管理者只能将备忘录传递给其他对象

    宽接口:

        原发器可以看到宽接口,允许它访问所需的所有数据,来返回先前的状态

    标准的备忘录模式实现机制依靠缓存实现

    备忘录可以仅仅储存增量改变

    备忘录与原型模式结合

    备忘录与命令模式结合

    优点:

        ○ 更好的封装性

        ○ 简化了原发器

        ○ 窄接口和宽接口

    缺点:

        ○ 可能会导致高开销

    本质:

        保存和恢复内部状态

    使用场景:

        ○ 保存一个对象在某一时刻的全部或者部分状态

        ○ 防止其他对象直接得到保存的状态

    

享元模式(Flyweight):

    场景:

        为系统加入权限控制的功能

        安全实体:

            被权限系统检测的对象,比如工资数据

        权限:

            需要被校验的权限对象,比如查看修改

        授权:

            对某些安全实体的某些权限分配给某些人员的过程

        验证:

            判断某个人员对某个安全实体是否拥有某个或某些权限的匹配过程

        权限的继承性:

            多个安全实体互相包含,某个安全实体没有相应的权限限制,那么它会继承包含它的安全实体的相应权限

        权限的最近匹配原则:

            找到最近的父节点的安全实体的权限

        缓存的问题:

            § 缓存时间长度的问题

            § 缓存数据和真实数据的同步问题

            § 缓存的多线程并发控制

        对象实例太多

    定义:

        运用共享技术有效地支持大量细粒度的对象

    重点:

        分离变与不变,内部状态不变,外部状态可变

    享元模式:

        组合模式合用,共享与不共享

        内部状态缓存和共享,外部状态不被缓存共享

    享元工厂来管理享元类

    将享元打包的组合类一般不需要共享

    优点:

        减少对象数量,节省内存空间

    缺点:

        维护共享对象,需要额外开销

    本质:

        分离与共享

    使用场景:

        使用了大量的细粒度对象

        使用大量对象,造成了很大的开销

        对象大多数状态都可以转变为外部状态,可以实现内部状态和外部状态的分离

        较少的共享对象取代很多对象组合,享元模式共享对象,组合对象来使用这些共享对象

    

解释器模式(Interpreter):

    场景:

        怎样灵活读取配置文件的内容

    问题:

        xml结构的变化导致读取xml文件内容的代码基本完全重写

    定义:

        给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

    功能:

        定义一种语法规则,用解释器模式来解释

    语法规则和解释器:

        一般一个解释器处理一条语法规则,一个语法规则可以有多种解释和处理

    优点:

        ○ 易于实现语法

        ○ 易于扩展新的语法

    缺点:

        ○ 不适合特别复杂的语法

    本质:

        分离实现,解释执行

    

装饰模式(Decorator):

    场景:

        复杂的奖金计算

    问题:

        经常会发生算法变动

        ○ 计算逻辑复杂

        ○ 要有足够灵活性

        ○ 动态的组合计算方式

    定义:

        动态地给一个对象添加一些额外的职责

    功能:

        动态地为对象添加功能,是从一个对象外部来给对象增加功能

    对象组合:

        尽量使用对象组合,而不是对象继承,来扩展和复用功能

    Java中典型的装饰模式应用:

        I/O流

    AOP:

        面向方面编程

        描述横切关注点的机制,将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,降低耦合度

    优点:

        比继承更灵活

        更容易复用功能

        简化高层定义

    缺点:

        产生很多细粒度对象

    本质:

        动态组合

        把复杂功能简单化,分散化,在运行期间根据需要来动态组合

    使用场景:

        不影响其他对象的情况下,以动态、透明的方式给对象添加职责

        不适合使用子类来进行扩展

    装饰模式、适配器模式:wrapper

    

职责链模式(Chain of Responsibility):

    场景:

        不同金额的报销费用,需要不同权限的领导

    问题:

        ○ 处理流程可能会变动

        ○ 各个处理环节的业务处理也会变动

    对象:

        使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止

    功能:

        客户端发出一个请求,有多个对象都有机会来处理这一个请求,但是客户端不知道究竟谁会来处理他的请求。让请求者和接受者解耦,动态地切换和组合接收者。

    功能链

    优点:

        ○ 请求者和接受者松散耦合

        ○ 动态组合职责

    缺点:

        ○ 产生很多细粒度对象

        ○ 不一定能被处理

    本质:

        分离职责,动态组合

    

桥接模式(Bridge):

    场景:

        发送提示消息,从基础功能上面扩展加急消息、特急消息、手机发送消息等等。

    问题:

        扩展起来不够方便

    定义:

        将抽象部分与它的实现部分分离,使它们都可以独立地变化

    什么是桥接:

        在不同的东西之间搭一个桥,让它们能够连接起来,可以互相通讯和使用

        在桥接模式中就是为被分离了的抽象部分和实现部分来搭桥

    桥接模式和继承:

        通常情况下,继承扩展功能变化维度都是一维的

        两个变化维度通常使用桥接模式

    JDBC:桥接模式

    优点:

        ○ 分离抽象和实现部分

        ○ 更好的扩展性

        ○ 可动态地切换实现

        ○ 可减少子类的个数

    本质:

        分离抽象和实现

 

访问者模式(Visitor):

    场景:

        扩展客户管理的功能

    缺点:

        相同的功能到不同的类中去实现

        给客户扩展新的功能,都需要改动企业客户的类和个人客户的类

    定义:

        表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作

    功能:

        给一系列对象透明地添加新功能,从而避免在维护期间对这一系列对象进行修改,而且还能变相实现复用访问者所具有的功能

    优点:

        ○ 好的扩展性

        ○ 好的复用性

        ○ 分离无关行为

    缺点:

        ○ 对象结构变化很困难

        ○ 破坏封装

    本质:

        预留通路,回调实现

发表评论

电子邮件地址不会被公开。 必填项已用*标注