# DesignPattern **Repository Path**: xpfcode/design-pattern ## Basic Information - **Project Name**: DesignPattern - **Description**: 设计模式 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-03-25 - **Last Updated**: 2022-04-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DesignPattern #### 介绍 采用Java语言,基于设计模式之禅,第2版的记录 #### 目录说明 com.xpffly.design 是基础包,其下各个包对应不同的设计模式 1. com.xpffly.design.factory 工厂模式 1.1 com.xpffly.design.factory.base 工厂方法模式 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。将一个类的实例化延迟到了子类中。 优点: ① 良好的封装性,代码结构清晰,降低模块间的耦合 ② 具有非常优秀的扩展性 ③ 屏蔽产品类,是典型的解耦框架 1.2 com.xpffly.design.factory.common 较为通用的工厂方法模式的变种 抽象类Product负责定义产品的共性,实现对事物最抽象的定义; ProductObjCreator为抽象工厂类,具体如何创建产品类是由具体的实现工厂ConcreteProductObjCreator完成 1.3 com.xpffly.design.factory.simple 为简单工厂模式(静态工厂模式) 简单工厂模式/静态工厂模式去掉了工厂的抽象类,并使用静态方法创建对象, 简化了类的创建过程。但由于少了工厂类的抽象类,因此工厂类的扩展比较困难,不符合开闭原则 1.4 com.xpffly.design.factory.abs 抽象工厂模式 抽象工厂模式是一种较为常用的模式, 定义:为创建一组相关或互相依赖的对象提供一个接口,而且无需指定他们的具体类 缺点:扩展困难(是指产品族扩展困难,但产品等级的扩展是很方便的) 优点:封装性好,符合开闭原则 2.com.xpffly.design.single 单例模式 定义:Ensure a class has only one instance,and provide a global point of access to it 确保某一个类只有一个实例,且自行实例化并向整个系统提供这个实例对象 3.com.xpffly.design.template 模板方法模式 定义:定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构 即可重定义该算法的某些特定步骤 抽象模板中的方法分为两类: ① 基本方法:基本方法也叫基本操作,是由子类实现的方法,并且在模板方法中被调用 ② 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑 为防止恶意操作,一般模板方法都加上final关键字,不允许被重写 钩子方法:可以让子类根据类中一个方法的返回值决定公共部分的执行结果 4.com.xpffly.design.builder 建造者模式 建造者模式也叫做生成器模式,是将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示 CarBuilder 为抽象建造者,BenzBuilder/BmBuilder为具体建造者 Director为导演类,负责安排已有模块的顺序,通知Builder进行建造 model包下为产品类,采用了模板方法模式 5.com.xpffly.design.proxy 代理模式 代理模式又称为委托模式; 在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务, 这个中介就是代理对象。例如,购买火车票不一定要去火车站买,可以通过 12306 网站或者去火车票代售点买。 又如找女朋友、找保姆、找工作等都可以通过找中介完成。 优点: - 职责清晰,具体角色是实现具体的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,代码清晰。 在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口; - 高扩展性,具体主题角色随时会发生变化,但是只要实现了接口,接口不变,代理类就可以不做任何修改继续使用,符合“开闭原则”。 另外,代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,同样符合开闭原则; 5.1 com.xpffly.design.proxy.statics 静态代理模式 5.2 com.xpffly.design.proxy.force 强制代理模式 真实的角色只有通过真实角色指定的代理类才可以访问,也就是真实角色管理代理角色 5.3 com.xpffly.design.proxy.dynamic 动态代理 6.com.xpffly.design.prototype 原型模式 定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象( 不通过new关键字创建对象,而是通过对象复制来实现创建对象的模式即为原型模式) 优点: ① 性能优良:原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多, 特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点. ② 逃避构造函数的约束:既是优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。 优点是减少了约束,缺点也是减少了约束。 使用场景: ① 资源优化场景:类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等 ② 性能和安全要求的场景:通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式 ③ 一个对象多个修改者的场景:一个对象需要提供给其它对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用 7.com.xpffly.design.mediator 中介者模式 定义:用一个中介对象封装一系列的对象交互,中介者使各个对象不需要显示的相互作用,从而使其耦合松散, 而且可以独立的改变他们之间的交互 优点:减少了类之间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,同时也降低了类之间的耦合 缺点:中介者模式的缺点是中介者会膨胀的很大,而且逻辑复杂,原本N个对象直接的相互依赖转换为中介者和同事类之间的依赖关系,同事类越多,终结者的逻辑就越复杂 8.com.xpffly.design.command 命令模式 定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,队请求排队或者记录请求日志,可以提供命令的撤销和回复功能 优点: ①类间解耦:调用者与接收者之间没有任何的依赖关系,调用者实现功能时只需调用Command抽象类的execute方法即可,不需要关心到底是哪个接收者执行 ②可扩展性:Command的子类可以非常容易的扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合 ③命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以下减少Command子类膨胀问题 缺点: 如果有N个命令,那么Command的子类就会有N个,这个类膨胀的非常大 9.com.xpffly.design.handler 责任链模式 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。 将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。 优点:责任链模式非常显著的优点是可以将请求与处理分开,请求者可以不用知道是谁在处理,矗立着可以不用知道 请求者的全貌,两者解耦,提升系统的灵活性。 缺点: ① 性能问题,每个请求都是从链头遍历到链尾,特别是链比较长的时候,性能是一个非常大的问题 ② 调试不方便,链条太长的时候,环节比较多由于采用了类似递归的方式,调式的时候逻辑可能比较复杂 10.com.xpffly.design.decorator 装饰模式 定义:动态的给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类会更加灵活( 通过子类继承是静态的给类增加功能,而装饰模式则是动态的增加功能。) 优点: ① 装饰类和被装饰类可以独立发展,而不会相互耦合 ② 装饰模式是继承关系的一个替代方案 ③ 装饰模式可以动态的扩展一个实现类的功能 ④ 装饰模式的扩展性很好 缺点:多层的装饰比较复杂 使用场景: ① 需要扩展一个类的功能,或给一个类增加附加功能 ② 需要动态的给一个对象增加功能,这些功能可以再动态的撤销 ③ 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式 common:包中为装饰模式通用代码 demo:包中为示例代码 11.com.xpffly.design.strategy 策略模式 定义:策略模式也叫政策模式,定义一组算法,将每个算法都封装起来,并且使他们之间可以互换 优点: ① 算法可以自由切换(即具体的策略实现类可以自由切换) ② 避免使用多重条件判断 ③ 扩展性良好 缺点: ① 策略类数量增多:每一个策略都是一个类,复用的可能性很小,类数量增多 ② 所有的策略类都需要对外暴露 使用场景: ① 多个类只有在算法或行为上稍有不同的场景 ② 算法需要自由切换的场景 ③ 需要屏蔽算法规则的场景 注意事项:如果一个策略家族中的具体策略数量超过4个,则需要考虑使用混合模式,解决策略类膨胀和对外 暴露的问题,否则日后的系统维护就会成为一个烫手山芋,谁都不想接 12.com.xpffly.design.adapter 适配器模式 适配器模式又称为 变压器模式也叫做包装模式 定义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法再一起工作的两个类能够在一起工作 优点: ① 适配器模式可以让两个没有任何关系的类在一起运行 ② 增加了类的透明性 ③ 提高了类的复用度 ④ 灵活性非常好:不需要时,删除适配器即可,对其他模块代码没有影响 缺点: 13.com.xpffly.design.iterator 迭代器模式 定义:迭代器模式提供一种方法访问一个容器对象中的各个元素,而不需要暴露该对象的内部细节( 迭代器模式目前是一个没落的模式,基本上没有会单独写一个迭代器,除非是产品性质的开发) Java中尽量不要自己写迭代器模式,使用Java提供的Iterator一般能够满足需求 14.com.xpffly.design.composite 组合模式 定义:组合模式也叫合成模式,有事又叫做部分-整体模式,主要是用来描述部分与整体的关系 (将对象组合成树形结构以表示‘部分-整体’的层次结构,使的用户对单个对象和组合对象的使用具有一致性) 组合模式中的几个角色: Component抽象组件:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。 Leaf叶子构件:叶子对象,其下再也没有其他的分支,就是遍历的最小单位 Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子结点形成一个树形结构。 优点: 1. 高层模块调用简单,高层模块不关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。 2. 节点自由添加,符合开闭原则,利于维护。 缺点:与依赖倒置原则冲突 15.com.xpffly.design.observer 观察者模式 定义:观察者模式定义了对象之间的一对多关系,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新。 观察者模式又叫做 发布--订阅模式。 出版者(主题)+订阅者(观察者)== 观察者模式。 优点: 1. 观察者与被观察之间是抽象耦合 2. 建立一套触发机制 缺点:观察者模式需要考虑一下开发效率和运行效率,一个被观察者多个观察者,开发和调试就会比较复杂,而且Java中的消息通知 默认是顺序执行的,一个观察者卡壳,会影响整体的执行效率。在这种情况下一般考虑采用异步的方式。 Tips: 1.异步处理需要考虑线程安全和队列的问题 16.com.xpffly.design.facade 门面(外观)模式 门面模式也叫外观模式,是一种比较常用的封装模式。 门面模式定义:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口, 使的子系统易于使用。 门面模式注重‘统一的对象’,也就是提供一个访问子系统的接口。 优点: 1. 减少系统之间的相互依赖 2. 提高了灵活性 3. 提高了安全性 缺点:不符合开闭原则(如果门面对象中有问题,就只能修改代码--风险很大) 使用场景: 1.为一个复杂的模块或子系统提供一个供外界访问的接口 2.子系统相对独立,外界对子系统的访问只需要黑箱操作即可 3.预防低水平人员带来的风险扩散 17.com.xpffly.design.memento 备忘录模式 备忘录模式定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态, ,这样以后就可以将对象恢复到原先保存的状态。(通俗的讲,备忘录模式就是一个对象的备份模式, 提供了一种程序数据的备份方法) 使用场景: 1. 需要保存和恢复数据的相关状态场景 2. 提供一个可回滚的操作,如撤销、后退等 3. 数据库连接的事务管理就是用的备忘录模式 18.com.xpffly.design.visitor 访问者模式 访问者模式定义:封装一些作用于某种数据结构中的各元素的操作, 它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。 意图:主要将数据结构与数据操作分离 主要解决:稳定的数据结构与易变的操作耦合问题 优点: 1. 符合单一职责原则 2. 具备优秀的扩展性 3. 灵活性非常高 缺点: 1.具体元素对访问者公布细节 2.具体元素变更比较困难 3.违背了依赖倒置转原则 19.com.xpffly.design.state 状态模式 状态模式定义:当一个对象内在状态改变时,允许其改变行为,这个对象看起来像改变了其类. 优点: 1、结构清晰,避免使用过多的Switch case或if else,避免了程序的复杂性,提高系统的可维护性 2、遵循设计原则,很好的体现了开闭原则和单一职责原则,每个状态是一个子类,你要增加状态就增加子类,你要修改状态时只需要修改一个子类就行了。 3、封装性非常好:状态的切换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换 缺点:子类会太多,容易造成类膨胀 使用场景: 1、行为随状态改变而改变的场景 2、条件、分支判断语句的替代者 20.com.xpffly.design.interpreter 解释器模式 21.com.xpffly.design.flyWeight 享元模式 22.com.xpffly.design.bridge 桥梁模式 以上为23中常见设计模式(工厂方法模式及抽象工厂模式均在---1、工厂模式中)