# Design Patterns **Repository Path**: neo5simple/Design-Patterns ## Basic Information - **Project Name**: Design Patterns - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2017-02-07 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 设计模式 + [x] Java 实例 + [ ] C++ 实例 # 分类 常见的 23 种设计模式可分为以下三大类 ## 创建型 + 单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 + 抽象工厂:提供创建一系列相关或相互依赖对象的接口,无须指定具体类 + 工厂方法:定义一个创建对象接口,让子类决定实例化哪一个类,实例化推迟到子类 + 建造模式:将一个复杂对象的构建与它的表示分离,使同样的构建过程可创建不同表示 + 原型模式:用原型实例指定创建对象的种类,通过拷贝这些原型来创建新的对象 ## 结构型 + 组合模式:将对象组合成树形结构以表示部分整体的关系,使单个对象和组合对象一致 + 外观模式:为子系统的一组接口提供一致的界面,让子系统更容易使用 + 代理模式:为其他对象提供一种代理以控制这个对象的访问 + 适配器模式:将类接口转换成客户希望的另一种接口,解决不兼容问题 + 装饰模式:动态给对象添加额外的职责,比生成子类更加灵活 + 桥模式:将抽象部分与实现部分分离,可以独立变化 + 享元模式:避免大量拥有相同内容的小类的开销,共享一个类 ## 行为型 + 迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,不暴露对象内部表示 + 观察者模式:定义对象间一对多的依赖关系,当状态改变时,其依赖都得到通知 + 模板方法:定义算法的骨架,子类可不改变算法结构而重定义特定步骤 + 命令模式:将请求封装成对象,可以用不同的请求对客户进行参数化,等请求操作 + 状态模式:允许对象在内部状态改变时改变它的行为。 + 策略模式:封装一系列算法,使它们可以相互替换,使得算法可以独立于客户 + 职责链模式:多个对象都有机会处理请求,避免请求的发送与接收者耦合关系 + 中介者模式:用中介对象封装一系列的对象交互 + 访问者模式:作用于某对象结构中各元素的操作,不改变元素类的前提下定义作用操作 + 解释器模式:给定一个语言,定义文法表示、解释器,使用表示解释语言中的句子 + 备忘录模式:在不破坏对象的前提下,捕获对象内部状态,在对象之外保存这个状态 # 分析 ## 策略模式 定义一系列对等的算法,使用相同的方法调用所有的算法,减少算法直接的耦合简化单元测试,可通过自己的接口单独测试;选择具体的实现是客户来承担的 ## 代理模式 + 远程代理,跨越空间的代理 + 虚拟代理,根据需要创建开销很大的对象,存放需要花费很长时间的真实对象 + 安全代理,控制真实对象的访问权限 + 智能指引,调用真实的对象时,处理另外一些事情,比如垃圾回收、加锁机制等 ## 工厂方法 定义一个用于创建对象的接口,让子类决定实例化具体类。 简单工厂模式中工厂类包含了必要的逻辑判断,根据客户端的条件来动态实例化相关类 抽象工程模式,易于交换产品系列,由于具体的工厂类只需要在初始化的时候出现一次就使得改变这个工厂变得十分容易,从而生产不同配置的产品。让具体的创建过程与客户端分离,客户端可以通过抽象接口操作实例,产品的具体类名也被具体工厂分离。 ## 原型模式 指定创建对象的种类,并通过拷贝这些原型创建新的对象 其实就是从一个对象再创建另外一个可定制的对象,而不需知道任何创建细节。一般在初始化信息不发生变化的情况下,克隆是最好的办法:隐藏创建细节,提高性能 ## 模板方法 定义一个操作中的算法骨架,将一些步骤延迟到子类中。使得子类可以不改变算法结构即可重定义某些特殊步骤。 通过把不变行为搬移到超类,去除子类中重复的代码来体现其优势,是很好复用的平台当不变的行为和可变的行为混合在类方法中,通过该模式可以解决一部分问题。 ## 外观模式 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,给子系统使用 在设计初期,要有意识将不同的两个层分离;在开发阶段子系统要不因重构演化而变得复杂;外观模式提供的接口可以减少它们之间的依赖,适合用于在遗留的难以维护又必须依赖的大型系统中,让用户直接与外观对象交互,外观类再去执行复杂操作。 ## 建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 用户只需要指定需要构建的类型就可以得到它们,具体建造的过层和细节是透明的,由于建造者隐藏了该产品是如何组装的,所以改变内部表示只需要额外定义一个建造者即可。 ## 观察者模式 定义一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,自动更新自己。 将一个系统分割成一系列相互协作的类,需要维护相关对象的一致性。这种一致性会使各类之间过分耦合,给维护、扩展和重用都带来不便。 当一个对象改变需要同时改变其他对象,而且这个对象并不知道具体有多少对象需要改变时,可以考虑使用这种模式。当一个抽象模型有两个方面,其中一方面依赖另一方面,这时用观察者将两者封装在独立的对象中使它们各自独立改变和复用。总的来说,这种模式是让双方依赖抽象,而不是具体的实现,使得各自变化都不会影响到另一个的变化。 委托是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。可以看成是对函数的抽象,委托的实例就代表一个具体函数。 一个委托可以搭载多个方法,多有方法被一次唤起,可以使得委托对象所搭载的方法并不需要同属于同一个类。 委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型。 ## 适配器模式 将一个类的接口转换成客户希望的另外一种接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 适配器可以使控制范围之外的一个原有对象与某个接口匹配,主要应用于系统复用一些现存类,但是接口又与复用环境要求不一致的情况。当使用一个已存在的类,如果使用它的接口,也就是它的方法和你的要求不相同时可以参考这种策略。 ## 备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个对象。这样以后就可将对象回复到原先保存的状态。 适合功能比较复杂的,但需要维护或记录属性历史的类,或需要保存的属性只是诸多中的一小部分时,组织者可根据备忘信息还原到前一个状态。命令模式的撤销操作状态可以使用这种模式。备忘录将复杂的对象内部信息对其他对象屏蔽起来,当角色状态改变时,有可能这个状态无效,这时就可以使用暂存的备忘录恢复。 ## 组合模式 将对象组合成树形结构以表示 部分-整体 的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 + 透明方式,在组件中声明所有用来管理子对象的方法,包含添加、移除等。叶节点和枝节点对外界没有区别,它们具备完全一致的行为接口;但是叶类本身不具备对应功能所以实现它是没有意义的。 + 安全方式,在组件接口中不声明添加、移除方法,那么子类的叶类也就不需要去实现它,而是在组件声明所有用来管理子类对象的方法。由于不够透明,所以树叶和树枝将不具备相同的接口,客户端调用需要做相应的判断,有诸多不便。 当需求中体现部分与整体层次的结构时,希望用户可以忽略组合对象与单个对象的不同统一使用组合结构中的所有对象时,就应该考虑组合模式。 组合模式定义了基本、组合对象的类层次结构。基本对象可以呗组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中任何用到基本对象的地方都可以使用组合对象。用户不用关心到底处理的一个叶节点还是处理一个组合组件,也用不着为定义组合而写一些选择判断语句。组合模式让用户可以一致地使用组合结构和单个对象。 ## 迭代器模式 提供一种方法顺序访问一个聚合对象中的各个元素,而不暴露其内部表示。适用于访问一个聚合对象,不管这些对象是什么都需要多种方式遍历的时候。 迭代器就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。 ## 单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点。让类自身负责保存它唯一实例。这个类可以保证没有其他实例可以被创建,并可以提供一个访问该实例的方法。 当有多线程访问的需求时,需要加锁。 可选择使用懒汉式单例和饿汉式单例,前者要在第一次被引用时才会被实例化;后者需要通过静态初始化的方式在自己被加载时将自己实例化。