Skip to content

设计模式概览

设计模式是软件开发中对常见设计问题的经验总结。它不是固定代码模板,而是一组可复用的设计思路,用来提升代码的可维护性、扩展性和可读性。

对初学者来说,学习设计模式的重点不是背出 23 个名字,而是理解:代码为什么会变复杂、变化点在哪里、对象之间应该怎样协作。

为什么要学习设计模式

  • 降低模块之间的耦合,避免一个改动牵动大片代码。
  • 提高代码复用能力,把稳定的结构沉淀下来。
  • 让系统更容易扩展和维护,面对需求变化时更从容。
  • 统一团队对常见设计问题的表达方式,例如“这里可以用策略模式”比长篇解释更高效。

23 种 GoF 设计模式是什么

GoF(Gang of Four)设计模式来自《设计模式:可复用面向对象软件的基础》。书中总结了 23 种经典模式,它们主要面向面向对象编程,但背后的思想同样适用于 Java、C#、TypeScript、Python 等语言。

这 23 种模式通常分为三类:

分类关注点包含模式
创建型对象如何创建单例、工厂方法、抽象工厂、建造者、原型
结构型类或对象如何组合适配器、桥接、组合、装饰器、外观、享元、代理
行为型对象之间如何协作责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者

为什么这样分类

分类的依据是“模式主要解决哪一类问题”。同一个模式可能也会影响其它方面,但通常有一个最核心的关注点。

创建型:把创建过程从使用过程里分离出来

当对象创建逻辑很简单时,直接 new 就很好。但如果创建对象需要选择实现类、拼装多个依赖、隐藏复杂构造步骤,创建型模式就能让调用方只关心“我要什么”,而不是“怎么一步步造出来”。

  • 单例关注“全局只需要一个实例”。
  • 工厂方法和抽象工厂关注“把具体产品的创建交给工厂”。
  • 建造者关注“分步骤构建复杂对象”。
  • 原型关注“通过复制已有对象创建新对象”。

结构型:让对象组合关系更灵活

结构型模式关注类与对象如何组织在一起。它们常用于适配旧接口、给对象动态增加能力、隐藏复杂子系统、表示树形结构,或者通过代理控制访问。

  • 适配器解决“接口不兼容”。
  • 桥接解决“多个维度独立变化”。
  • 组合解决“整体和部分用一致方式处理”。
  • 装饰器解决“运行期叠加功能”。
  • 外观解决“给复杂系统提供简单入口”。
  • 享元解决“大量相似对象的共享”。
  • 代理解决“访问前后需要控制或增强”。

行为型:安排对象之间的职责与协作

行为型模式关注流程、通信和职责分配。它们帮助我们把条件分支、状态变化、事件通知、命令执行、算法步骤等逻辑组织得更清楚。

  • 策略、状态、模板方法关注“行为如何变化”。
  • 观察者、中介者、责任链关注“对象如何通信”。
  • 命令、备忘录、访问者关注“把操作、历史或访问逻辑独立出来”。
  • 迭代器、解释器关注“遍历集合或解释规则”。

推荐学习路线

可以按“先原则、再高频、后复杂”的顺序学习,不必一开始就平均用力。

  1. 先理解设计原则:单一职责、开闭原则、依赖倒置等原则能帮助你判断模式为什么成立。
  2. 从最常见的模式开始:策略、工厂方法、单例、模板方法、观察者、适配器、装饰器、代理、外观,这些模式在业务代码和框架源码中很常见。
  3. 结合业务场景理解分类:遇到“创建复杂”看创建型,遇到“对象关系复杂”看结构型,遇到“流程协作复杂”看行为型。
  4. 再学习相似模式的区别:例如策略和状态都能消除分支,但策略通常由外部选择算法,状态通常由对象内部状态驱动行为切换。
  5. 最后补齐低频或更抽象的模式:如解释器、访问者、享元,它们使用场景更明确,理解典型案例即可。

建议每学一个模式都问四个问题:它解决什么问题?不使用会怎样?它引入了哪些角色?使用后增加了哪些成本?

如何判断是否需要设计模式

设计模式不是越多越好。可以用下面几个信号判断是否值得引入:

  • 存在明确变化点:例如支付方式、导出格式、通知渠道会持续增加,适合考虑策略、工厂等模式。
  • 重复分支开始扩散:多个地方都有相似的 if/elseswitch,修改一个规则要改很多文件。
  • 对象创建越来越复杂:构造参数很多、创建步骤固定、实现类选择逻辑散落在业务代码中。
  • 调用方知道太多细节:业务代码需要了解子系统内部多个类的调用顺序,可能需要外观或封装服务。
  • 扩展总是伴随修改稳定代码:每次新增功能都要改核心流程,说明可能违反开闭原则。

如果只是一次性逻辑、需求还不稳定、代码量很小,直接写清楚通常更好。模式应该服务于可维护性,而不是为了显得“高级”。

常见误区

  1. 把设计模式当成代码模板:模式描述的是角色和协作方式,不同语言和项目中的实现可以不同。
  2. 为了使用模式而使用模式:没有变化点时强行抽象,会增加类数量和理解成本。
  3. 只记类图,不理解问题:不知道模式解决的问题,就很容易在不合适的场景套用。
  4. 忽略模式带来的成本:模式通常会增加间接层,降低直接阅读代码的速度,需要用扩展收益来抵消。
  5. 认为模式能替代设计原则:设计原则帮助判断方向,模式只是常见解决方案之一。
  6. 一次性设计过度完整:初学时容易提前预留很多扩展点,但真实需求未必会来。更推荐在变化出现后逐步重构。

目录

基础

创建型模式

创建型模式关注对象创建过程,把对象的创建和使用解耦。

结构型模式

结构型模式关注类或对象之间的组合关系,让系统结构更灵活。

行为型模式

行为型模式关注对象之间的职责分配和协作方式。

二维码手机扫码查看