张晗的个人博客

技术的价值是业务

模式描述

策略模式(Strategy)定义了一系列行为,将每个行为分别封装起来,让它们可以互相替换,使得行为的变化可以独立于使用它们的客户端。

优点

  1. 提供了一组 Strategy;
  2. 组合代替了继承;
  3. 消除分支;
  4. client 选择 Strategy 实现;

缺点

  1. client 需要了解 Strategy 实现的不同;
  2. 某些 Strategy 用不到所有 Context 传来的数据,增加通信成本;
  3. 增加了类的数目;

应用场景

  1. 替换的仅仅是类中的行为;
  2. 行为中的数据对用户是隐藏的;
阅读全文 »

模式描述

工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类,使得一个类的实例化延迟到其子类。

优点

  1. 给子类创建对象预留扩展点;
  2. client 通过 Creator 间接创建对象;

缺点

  1. Creator 实现变多;

应用场景

  1. 一个类希望由它的子类来创建对象时;
  2. 一个类不知道创建对象的类时;
阅读全文 »

DATE CHANGELOG
2023年4月23日 初始化
2023年4月30日 添加代码库
2023年5月9日 添加参考书

设计模式是记录 OOP 中重要和重复出现的设计,用来对抗未来的需求和变化,帮助设计者更快、更好地完成系统设计的模板或者说套路。

概览

设计模式 意图 重构原因 扩展点
抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 显式创建类对象 对平台的依赖 显式对象的依赖 紧耦合 产品对象家族
建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 算法依赖 如何创建一个组合对象
工厂方法模式 定义一个用于创建对象的接口,让子类决定将哪一个类实例化 Factory Method 使一个类的实例化延迟到其子类 显式创建类对象 被实例化的子类
单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点 一个类唯一实例
适配器模式 将一个类的接口转换成另外一个接口 Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 无法方便对类进行修改 对象的接口
桥接模式 将抽象部分与它的实现部分分离,使它们都可以独立地变化 对平台的依赖 显式对象的依赖 通过生成子类扩充功能 对象的实现
装饰者模式 动态地给一个对象添加一些额外的职责 就扩展功能而言,Decorator 模式比生成子类方式更为灵活 无法方便对类进行修改 通过生成子类扩充功能 对象的职责,不生成子类
代理模式 为其他对象提供一个代理以控制对这个对象的访问 显式对象的依赖 如何访问对象;对象的位置
责任链模式 为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求 将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 对特殊操作的依赖 通过生成子类扩充功能 紧耦合 满足一个对象的请求
迭代器模式 提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示 算法依赖 如何遍历、访问一个可迭代对象
观察者模式 定义对象间的一种一对多的依赖关系 以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新 通过生成子类扩充功能 紧耦合 多个对象依赖另一个对象 这些对象如何保存
状态模式 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类 对象的状态
策略模式 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换 本模式使得算法的变化可独立于使用它的客户。 算法依赖 通过生成子类扩充功能 算法
模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中 Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 算法依赖 算法的某些步骤
命令模式 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化 对请求排队或记录请求日志,以及支持可取消的操作 对特殊操作的依赖 紧耦合 合适、怎样满足请求
原型模式 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象 显式创建类对象 被实例化的类
组合模式 将对象组合成树形结构以表示“部分-整体”的层次结构 Composite 使得客户对单个对象和复合对象的使用具有一致性 通过生成子类扩充功能 一个对象的结构和组成
门面模式 为子系统中的一组接口提供一个一致的界面 Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 紧耦合 一个子系统的接口
享元模式 运用共享技术有效地支持大量细粒度的对象 对象的存储开销
解释器模式 给定一个语言,定义它的方法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子 一个语言的文法及解释
中介者模式 用一个中介对象来封装一系列的对象交互 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互 紧耦合 对象间怎样交互、和谁交互
备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态 这样以后就可将该对象恢复到保存的状态 显式对象的依赖 对象的哪些信息可以存放在对象外 何时存储在对象外
访问者模式 表示一个作用于某对象结构中的各元素的操作 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作 算法依赖 无法方便对类进行修改 作用在对象的操作,不修改对象的类

分类

加粗为常用的设计模式。

类范围是静态的,在编译期确定;对象范围是动态的,在运行时确定。

创建型 creational

关注对象的创建。类范围是将创建工作延迟到子类,对象范围则将创建工作延迟到另一个对象中。

对象
工厂方法模式 (Factory Method) 抽象工厂模式 (Abstract Factory)
建造者模式 (Builder)
单例模式 (Singleton)
原型模式 (Prototype)

结构型 structural

关注类或对象的组装。类范围使用继承来组装类,对象范围则描述了对象的组装方式。

对象
适配器模式 (Adapter) 适配器模式 (Adapter)
桥接模式 (Bridge)
装饰者模式 (Decorator)
代理模式 (Proxy)
组合模式 (Composite)
门面模式 (Facade)
享元模式 (Flyweight)

行为型 behavioral

关注类或对象的交互和职责分配。类范围使用继承描述算法和控制流,对象范围则描述了一组对象如何协作完成单个对象无法完成的任务。

对象
模板方法模式 (Template Method)
解释器模式 (Interpreter)
责任链模式 (Chain of Responsibility)
迭代器模式 (Iterator)
观察者模式 (Observer)
状态模式 (State)
策略模式 (Strategy)
中介者模式 (Mediator)
命令模式 (Command)
备忘录模式 (Memento)
访问者模式 (Visitor)

模式如何解决设计问题

  1. 寻找合适的对象。如何挑选合适对象来对现实世界进行抽象,以灵活的设计应对未来需求的变化;
  2. 决定对象的粒度;
  3. 定义接口及操作;
  4. 实现接口。通过接口、类、抽象类来实现定义好的接口;
  5. 复用接口。通过组合、委托等方式来复用定义的接口;

选择模式的一般方法

  1. 考虑模式如何解决设计问题;
  2. 浏览模式意图;
  3. 研究目的相似模式;
  4. 查看模式解决问题聚焦的领域;
  5. 确定模式可变的方面;

使用模式的一般方法

  1. 浏览一遍模式。重点关注模式适用的场景和需要做出的权衡;
  2. 理解模式中类和对象的关联;
  3. 查看模式示例代码;
  4. 进行移植;

注意

设计模式不可以随意使用。通常情况下,引入设计模式在获得灵活性和可变性的同时,会使设计变得更复杂和难以理解。

代码库

design-patterns-examples

参考书

  • 设计模式:可复用面向对象软件的基础

  • 设计模式之美

  • 大话设计模式:Java 溢彩加强版

  • Go语言设计模式(双色版)

    设计模式中,主要关注 UML 类图,可作者却用第一张 70% 第一章的篇幅来介绍 UML 基础,对重点的类图并没有着墨太多。最后一章也用了 8% 的内容来介绍软件架构,有些凑字数。

    我认为本书是对《设计模式:可复用面型对象软件的基础》中内容的转译,没有看到作者的独到见解。此外,书籍源代码竟然没有 POST 到扉页,而是要关注公众号获取,体验很差。

    对于没有编程经验的人来说,设计模式来入门挑战比较大,不推荐作为前几部来阅读。对于有其他语言经验的人,本书不是一个好的选择。建议看 《设计模式:可复用面型对象软件的基础》和 《大话设计模式》。

  • refactoringguru

0%