跳转到内容

设计模式

设计模式是针对特定软件设计情境的可重用蓝图,经典的 GoF 23 种模式被划分为以下三大类:

1.1. 创建型模式 (Creational Patterns)

Section titled “1.1. 创建型模式 (Creational Patterns)”

创建型模式关注 对象的创建过程,通过将对象的创建与使用分离,使系统在对象实例化时更具弹性与通用性。

模式名称作用与目标典型工程实例
单例模式
(Singleton)
确保一个类在全局范围内只有一个实例,并提供一个统一的访问点。配置文件管理器、线程池、全局日志收集器。
工厂方法模式
(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个具体类,实现延迟实例化。数据库连接库(定义抽象连接,具体连接由 MySQL/PostgreSQL 驱动子类决定)。
抽象工厂模式
(Abstract Factory)
提供一个接口,用于创建一系列相关或相互依赖的对象族,而无须指定它们具体的具体类。跨平台 UI 皮肤库(同时创建 Windows 风格的按钮和文本框,或 macOS 风格 the 同类组件)。
建造者模式
(Builder)
将一个复杂对象的构建步骤与其最终表示分离,使同样的构建过程可以创建不同的表示。带有大量可选配置参数的复杂对象构造(如 HttpClientConfigSQLQueryBuilder)。
原型模式
(Prototype)
通过复制(克隆)已有实例来创建新的对象,而不是通过常规构造器实例化。涉及昂贵资源创建的对象(如复杂数据结构),通过浅克隆/深克隆提升性能。

1.2. 结构型模式 (Structural Patterns)

Section titled “1.2. 结构型模式 (Structural Patterns)”

结构型模式关注 类或对象的组合,旨在通过封装、代理或桥接方式将对象组合成更大、更灵活的结构。

模式名称作用与目标典型工程实例
适配器模式
(Adapter)
将一个类的接口转换成客户端所期待的另一个接口,使原本接口不兼容的类能协同工作。将第三方支付 API(如旧版 XML 接口)适配为系统内部的统一 JSON 接口。
装饰器模式
(Decorator)
动态地给一个对象添加额外的职责。相比直接继承,装饰器提供了更灵活的扩展方式。I/O 输入输出流(如 Java 中的 BufferedInputStream 装饰 FileInputStream)。
代理模式
(Proxy)
为另一个对象提供一个替身或占位符,以控制、过滤或延迟对这个真实对象的访问。虚拟代理(大图片延迟加载)、安全保护代理(权限校验)、AOP 动态代理。
组合模式
(Composite)
将对象组合成树形结构以表示“部分-整体”的层次关系,让客户端对单个对象和组合对象保持一致的使用方式。文件系统管理(文件夹包含文件和子文件夹)、XML/HTML DOM 树解析。
桥接模式
(Bridge)
将抽象部分与它的实现部分分离,使它们都可以独立地发生维度上的变化。图形形状(圆、方)与不同渲染平台(OpenGL、DirectX)的多维度独立变化。
享元模式
(Flyweight)
运用共享技术高效支持大量细粒度对象的复用,极大减少内存占用。字符对象池(如 Word 编辑器中的字符对象)、JVM 中的 String 常量池。
外观模式
(Facade)
为子系统中的一组接口提供一个统一的高层接口,使该子系统更容易被外部客户端使用。复杂的微服务调用链整合(如将下单、扣减库存、物流接口合并为一个 Facade 接口)。

1.3. 行为型模式 (Behavioral Patterns)

Section titled “1.3. 行为型模式 (Behavioral Patterns)”

行为型模式关注 对象之间的通信与职责分配,以及算法的封装和协作流程。

模式名称作用与目标典型工程实例
观察者模式
(Observer)
定义对象间的一对多依赖关系。当一个对象状态改变时,所有依赖者都会自动收到通知并更新。事件驱动系统(Event Broker)、GUI 事件监听器、发布-订阅模型。
策略模式
(Strategy)
定义一系列算法并将其逐个封装,使它们可以动态相互替换。算法的变化不影响使用方的逻辑。多支付方式选择(支付宝、微信、银联)、不同压缩格式(ZIP、RAR)的动态切换。
模板方法模式
(Template Method)
定义一个算法的骨架,而将一些可变步骤延迟到子类中实现。子类可以在不改变整体算法结构的前提下重定义特定步骤。通用的数据解析器流程(打开连接 -> 解析数据 -> 关闭连接),具体解析由 XML/JSON 子类实现。
命令模式
(Command)
将请求封装为独立的对象,从而支持请求队列、撤销操作(Undo)及宏命令。文本编辑器中各种菜单操作的封装、线程池工作队列中的 Task 对象。
迭代器模式
(Iterator)
提供一种方法顺序访问一个聚合对象中的各个元素,而又无须暴露该聚合对象的内部物理表示。集合框架(List、Set、Map)的 iterator() 遍历机制。
职责链模式
(Chain of Responsibility)
避免请求发送者和接收者发生耦合,将多个处理者连接成一条链,请求沿着链传递直至被处理。Web 服务器中的 Filter 过滤器链、日志记录级别过滤系统、多级请假审批流。
备忘录模式
(Memento)
在不破坏封装性的前提下,捕获并保存一个对象的内部状态,以便未来将其恢复到该先前状态。文本编辑器的撤销(Ctrl+Z)历史记录、游戏内的存档/读档机制。
状态模式
(State)
允许一个对象在其内部状态改变时改变其行为,看起来就像改变了其对应的类。自动售货机状态机(未投币、已投币、售出中)、电梯运行状态控制。
访问者模式
(Visitor)
表示一个作用于某对象结构中各元素的操作,允许在不改变元素类的前提下定义作用于这些元素的新操作。编译器的 AST(抽象语法树)遍历分析(语义检查、代码格式化、优化器)。
中介者模式
(Mediator)
用一个中介对象来封装一系列对象的交互,使各个对象无须显式相互引用,降低系统耦合度。机场飞行交通管制系统、微服务架构中的 ESB/中介服务。
解释器模式
(Interpreter)
给定一门语言,定义它的文法表示,并定义一个解释器,用于解释该语言中的句子。正则表达式引擎、SQL 语法解析器、简单数学公式计算器。

2.1. 简单工厂 Vs 工厂方法 Vs 抽象工厂

Section titled “2.1. 简单工厂 Vs 工厂方法 Vs 抽象工厂”
  • 简单工厂: 并非 GoF 标准模式。由一个统一的工厂类根据输入参数决定创建哪一种产品,违反开闭原则(新增产品需修改工厂类代码)。
  • 工厂方法: 每个具体产品都对应一个具体工厂类。通过多态解耦:具体具体工厂只关注单类产品的创建,职责单一,符合开闭原则。
  • 抽象工厂: 解决产品族(多类相关联的产品)的创建问题。例如同时生产一个系统主题下的 Button、Border 和 Window。
  • 桥接模式: 属于 结构型模式,主要用于 解耦抽象与实现,处理两个甚至多个维度独立变化的情况,目的是避免由于多维度继承带来的类爆炸。
  • 策略模式: 属于 行为型模式,主要用于 封装可变算法,让客户端能够动态地切换和替换具体业务行为,目的是消除复杂的 if-else 条件判断。

2.3. 建造者模式 Vs 模板方法模式

Section titled “2.3. 建造者模式 Vs 模板方法模式”
  • 建造者模式: 属于 创建型模式,专注于 复杂对象的组装与创建过程,通过 Director 编排具体建造步骤来产出最终对象。
  • 模板方法模式: 属于 行为型模式,专注于 算法逻辑流程的控制,在父类确定一个行为骨架,部分步骤留给子类在运行时填充。

在重构指南中,Martin Fowler 指出 “过长的方法”(Long Method) 是最经典的代码坏味道之一。方法如果过于冗长,往往意味着它承担了过多的职责,导致系统极难维护。