# javadp **Repository Path**: fuckjava/javadp ## Basic Information - **Project Name**: javadp - **Description**: Java设计模式示例代码(Java Design Pattern) - **Primary Language**: Java - **License**: AFL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2020-04-09 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [TOC] ## 设计模式 ### 1. 简单工厂模式 #### 简介 >实现面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。 ![6705fca281b30f0a17290495cf7e4111.png](en-resource://database/3090:1) #### 优点 1. 工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 * * * ### 2.策略模式 #### 简介 >它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 ![f93866ef06e5d2cb30dbccfc48bfdfd9.png](en-resource://database/3096:1) #### 优点 1.简化了单元测试,每个算法斗有自己的类,可以通过自己的接口单独测试 2.可以消除行为类中的条件语句,比如swich条件分支 #### 应用 * 只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性 * 策略模式与简单工厂模式结合,具体实现可以由Context来承担,大大减轻了客户端的职责 * * * ### 3.装饰模式 #### 简介 >动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活 #### 优点 1. 把类中的装饰功能从类中搬移去除,这样可以简化原有的类 2. 有效地把类的核心职责和装饰功能区分开了,可以去除相关类中的重复逻辑 #### 应用 * 当系统需要新功能的时候,是向旧类中添加新的代码。这些新加的代码通常装饰了原有类的核心心职责和主要行为。 * 新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,装饰模式提供了非常好的解决方案 * * * ### 4.代理模式 #### 简介 >代理模式,为其他对象提供一种代理以控制对这个对象的访问。 ![d383f468ffbf57b76f5549b6706676f8.png](en-resource://database/3114:2) #### 优点 #### 应用 * 远程代理,为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同的地址空间的事实。如:远程访问 * 虚拟代理,根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。如:虚拟代理了真实图片,此时代理存储了真实图片的路径和尺寸 * 安全代理,用来控制真实对象访问时的权限。如:对象有不同的访问权限 * 智能指引,时指当调用真实的对象时,代理处理另外一些事。如:计算真实对象的引用次数 * * * ### 5.工厂方法模式 #### 简介 >定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类 ![5603f9f8030a690942753588c2d332c9.png](en-resource://database/3124:1) #### 优点 1. 克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点 2. 保持了简单工厂模式的优点,克服了它的缺点 #### 缺点 1. 每加一个产品,就需要加一个产品的工厂类,增加了额外的开发量 * * * ### 4.代理模式 #### 简介 代理模式,为其他对象提供一种代理以控制对这个对象的访问。 ![d383f468ffbf57b76f5549b6706676f8.png](en-resource://database/3114:2) #### 优点 #### 应用 * 远程代理,为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同的地址空间的事实。如:远程访问 * 虚拟代理,根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。如:虚拟代理了真实图片,此时代理存储了真实图片的路径和尺寸 * 安全代理,用来控制真实对象访问时的权限。如:对象有不同的访问权限 * 智能指引,时指当调用真实的对象时,代理处理另外一些事。如:计算真实对象的引用次数 * * * ### 6.原型模式 #### 简介 >用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 ![5f89f5755aa60ba942c12989887814f0.png](en-resource://database/3240:1) #### 优点 1. 从一个对象创建另一个可定制的对象,而且不需知道任何创建的细节。 #### 缺点 1. 浅复制和深复制的区别 * * * ### 7.模板方法模式 #### 简介 >定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可以不改变一个算法的结构即可重定义该算法的某些特定步骤 ![e723658f91d1a1a6be78853e44451b90.png](en-resource://database/3244:1) #### 优点 1. 提供一个很好的代码复用平台,通过吧不变的行为搬到超类,去除子类中的重复代码来体现它的优势 #### 缺点 * * * ### 8.外观模式 #### 简介 >为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,使得这个系统更加容易使用 ![1dbe73553f56e5c1ed09934da33b8346.png](en-resource://database/3246:1) #### 优点 1. 解决维护一个遗留的大型系统时遇到的问题,减少不必要的麻烦 #### 缺点 ### 9.建造模式 #### 简介 >将一个复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 ![59a6a6aadbdae283155ed86acbf35e07.png](en-resource://database/3248:1) #### 优点 1.使得建造代码与表示代码分离,由于建造者隐藏了该产品的细节,若需改变一个产品内部表示,只需要定义一个具体的建造者就可以了 #### 缺点 * * * ### 10.观察者模式(发布-订阅模式) #### 简介 >定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 ![a9cd8bba13461a59f4254ea0af6a2a51.png](en-resource://database/3250:1) #### 优点 1. 将一个系统分割成一系列相互协作的累有一个很不好的副作用,那就需要维护相关对象间的一致性。这样维护,拓展和重用都带来不便 2. 观察者模式的工作其实就是解除耦合,让耦合双方都依赖于抽象,而不是具体 #### 缺点 1. 万一没有了抽象观察者这样的接口,通知就完不成了 #### 应用场景 1. 当一个对象改变,同时需要联动改变其他对象 2. 不知道有多少对象需要改变时,应该考虑使用观察者模式 * * * ### 11.抽象工厂模式 #### 简介 >提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 ![669701ed9f33802e14ea9a24da0d6df8.png](en-resource://database/3252:1) #### 优点 1. 便于交换产品系列,应用中只需要在初始化的时候出现一次,使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂。 2. 它使得具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂实现分离。 #### 缺点 1. 抽象工厂方便切换DB,但如果新增表,会导致需要更改很多地方 #### 应用场景 1. 切换DB #### 拓展 1. 用简单工厂改进抽象工厂 2. 用反射+抽象工厂的数据访问程序 3. 用反射+配置文件实线数据访问程序 * * * ### 12.状态模式 #### 简介 >当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 ![423af34ad117667f9e3760498ddb6034.png](en-resource://database/3254:1) #### 优点 1. 主要解决当控制一个对象状态转换的条件表达式过于复杂的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑化。 2. 将特定状态相关的行为局部化,并且将不同状态的行为分割开来。 3. 消除了庞大的条件分支语句 #### 缺点 #### 应用场景 1. 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑 #### 拓展 * * * ### 13.适配器模式(Adapter) #### 简介 >将一个类的接口转换层客户希望另一个接口,它使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 ![1eecd7b37bf6a2f57ea5354cc7aa790b.png](en-resource://database/3256:1) #### 优点 1. 客户代码可以统一调用同一接口就行了,这样可以更简单,更直接,更紧凑 #### 缺点 #### 应用场景 1. 在双方不太容易修改的时候再使用适配器模式适配 #### 拓展 * * * ### 14.备忘录模式 #### 简介 >在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态 ![37c8ee83a981db729ec2c9c136f9b6c6.png](en-resource://database/3258:1) #### 优点 1. 备忘录模式可以把复杂的对象内部信息对其他的对象屏蔽起来 #### 缺点 1. 角色状态需要完整存储到备忘录对象中,如果状态数据大很多,那么在资源消耗上,备忘录对象会非常耗内存 #### 应用场景 1. 备忘录模式比较适用于功能比较复杂的,但需要维护或记录属性的历史类,或者需要保存的属性只是众多属性的一小部分时,可以根据保存的备忘信息还原到前一状态 2. 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。 #### 拓展 * * * ### 15.组合模式(整体与部分可以被一致对待) #### 简介 >将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一体性 ![d110b7836e5c158fd9eb59978c168310.png](en-resource://database/3260:1) #### 优点 1. 组合模式让客户可以一致的使用组合结构和单个对象 #### 缺点 #### 应用场景 1. 当你发现是需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一使用组合结构中的所有对象时,就应该考虑组合模式了(分公司,办事处) #### 拓展 * * * ### 16.迭代器模式 #### 简介 >提供一种方法顺序访问一个聚合对象中各个元素,而不是暴露该对象的内部表示 ![965815b5ef6cc7f830587018a5e1636a.png](en-resource://database/3262:1) #### 优点 #### 缺点 1. 迭代器模式的使用价值不如学习价值大了(foreach in) #### 应用场景 1. 当你需要访问一个聚集对象,而且不管这些对象时什么都需要遍历的时候,你就应该考虑迭代器模式 #### 拓展 * * * ### 17.单例模式 #### 简介 >保证一个类仅有一个实例,并提供一个访问它的全局访问点 ![30be87133f494ffd37eef7087ec0524d.png](en-resource://database/3264:1) #### 优点 1. 保证实例的唯一性 2. 可以严格空值客户端怎样访问和何时访问 #### 缺点 1. 需要注意线程安全问题 #### 应用场景 1. 当你需要访问一个聚集对象,而且不管这些对象时什么都需要遍历的时候,你就应该考虑迭代器模式 #### 拓展 1. 多线程时的单例 2. 双重锁定 3. 静态初始化 4. 懒汉饿汉 1. 饿汉:类一加载就实例化,提前占用系统资源(需要双重锁定保证安全性) 2. 懒汉:第一次被引用时,才会将自己实例化 * * * ### 18.桥接模式 #### 简介 >将抽象部分与它的实现部分分离,使它们都可以独立的变化 ![4684e752438947a9847858d6dc8222d2.png](en-resource://database/3268:1) #### 优点 1. 实现程序间的松耦合 #### 缺点 #### 应用场景 #### 拓展 * * * ### 19.命令模式 #### 简介 >将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作! ![de3bc9c27d07ce61da29a71a94b00714.png](en-resource://database/3270:1) #### 优点 1. 能较容易设计一个命令队列 2. 可以较容易地将命令记入日志 3. 允许接收请求的一方决定是否要否决请求 4. 可以容易地实现对请求的撤销和重做 5. 加新的具体命令类不影响其他的类,因此增加新的具体命令类很容易 6. 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开 #### 缺点 #### 应用场景 #### 拓展 * * * ### 20.职责链模式 #### 简介 >使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 ![f0dc42334fc8d89a654aba858336eac9.png](en-resource://database/3272:1) #### 优点 1. 请求者不用管哪个对象会处理,反正该请求会被处理 2. 降低了代码的耦合度 3. 可以随时增加或修改一个请求的结构,增强了给对象指派职责的灵活性 #### 缺点 #### 应用场景 #### 拓展 * * * ### 21.中介者模式 #### 简介 >用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互 ![cfcd737e93ca04489d9db83dc4345148.png](en-resource://database/3274:1) #### 优点 1. 降低了代码的耦合度,使得可以独立地改变和复用代码 2. 把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,看系统更宏观 #### 缺点 1. 把交互的复杂性变成了中介者的复杂性 #### 应用场景 1. 中介者一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。 #### 拓展 1. 计算器窗体 * * * ### 22.享元模式 #### 简介 >运用共享计数有效地支持大量细粒度的对象 ![9f5aa722adca03afda0c074903e8dcc5.png](en-resource://database/3276:1) #### 优点 1. 可以避免大量非常相似的类的开销 #### 缺点 1. 把交互的复杂性变成了中介者的复杂性 #### 应用场景 1. 如果一个应用程序中使用了大量的对象,而大量的这些造成了很大的存储开销就应该考虑,还有就是这个对象大多数状态可以外部状态,如果删除对象的外部状态,可以用相对较少的共享对象取代多组对象,此时可以考虑使用。 #### 拓展 * * * ### 22.解释器模式 #### 简介 >给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 ![110e5cb22f095f737f14521453029ade.png](en-resource://database/3278:0) #### 优点 1. 很容易改变和拓展文法,因为该模式使用类来表示文法规则,你可以使用继承来改变或拓展文法,也比较容易实现文法。 #### 缺点 1. 每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护,建议当文法非常复杂时,使用其他技术,如语法分析程序或编译器生成器来处理 #### 应用场景 1. 当有一个语言需要解释执行,并且你可以将该语言中的句子表示一个抽象语法树时,可以使用解释器模式(如正则表达式,浏览器) #### 拓展 * * * ### 23.访问者模式 #### 简介 >表示一个作用于某对象结构中各元素的操作,它使你可以在不改变元素的类的前提下定义作用于这些元素的新操作 ![5f48a8f1ef39e84f93a9b9a6f7b855d0.png](en-resource://database/3280:0) #### 优点 1. 它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化 2. 增加新的操作很容易,因为增加的操作就以为增加一个新的访问者 #### 缺点 1. 使增加新的数据结构变得困难了(GOF:大多数时候你不需要访问者模式,如果需要,那就是真的需要了) #### 应用场景 #### 拓展 * * *