Skip to content

设计模式概述

设计模式是指在软件设计中,对反复出现的问题提出的通用、可复用的解决方案。它不是具体的代码片段,而是一种经过验证的设计模板或思路,可以根据具体场景进行调整和实现。设计模式是软件开发中常见问题的典型解决方案,目的是让代码更易维护、易扩展、易理解、可复用。

23 种经典设计模式全览

根据 GoF(Gang of Four)的经典分类,设计模式分为创建型、结构型和行为型三大类。

创建型模式(5 种)

模式名称核心思想典型应用场景现代替代方案
单例保证一个类仅有一个实例配置管理器、日志记录器、数据库连接池依赖注入容器、模块化系统
工厂方法定义创建对象的接口,由子类决定实例化框架扩展点、插件系统依赖注入、函数式工厂
抽象工厂创建产品族,无需指定具体类跨平台 UI 组件、数据库驱动构建器模式、依赖注入
建造者分步骤构建复杂对象配置对象构建、DSL 链式调用数据类、命名参数
原型通过复制现有对象创建新对象对象池、减少初始化开销深拷贝函数、不可变数据结构

结构型模式(7 种)

模式名称核心思想典型应用场景现代替代方案
适配器转换不兼容接口新旧系统对接、第三方库集成函数包装器、中间件
桥接分离抽象与实现跨平台渲染、形状与颜色组合组合优于继承、函数组合
组合树形结构表示部分-整体层次文件系统、UI 组件树递归数据结构、代数数据类型
装饰器动态添加功能中间件系统、流处理高阶函数、函数组合
外观为复杂子系统提供简单接口API 网关、库封装模块化导出、Facade 函数
享元共享对象减少内存对象池、字符串驻留不可变数据、结构共享
代理控制对象访问远程代理、懒加载、访问控制函数包装、惰性求值

行为型模式(11 种)

模式名称核心思想典型应用场景现代替代方案
观察者一对多依赖,状态变化通知事件驱动架构、响应式 UI响应式流、信号机制
策略算法封装,可互换支付方式、排序算法、验证规则一等函数、模式匹配
命令请求封装为对象撤销重做、任务队列、宏命令一等函数、代数数据类型
状态状态改变行为工作流、订单状态、游戏角色状态机、模式匹配
模板方法父类定义算法骨架框架设计、钩子方法高阶函数、组合
责任链请求沿处理链传递日志记录、异常处理、中间件函数组合、管道模式
访问者不改变类结构定义新操作编译器语法树、文档生成模式匹配、多方法
中介者封装对象交互聊天室、表单验证事件总线、响应式状态
迭代器统一遍历集合接口集合遍历、生成器惰性序列、for 推导
备忘录捕获对象内部状态撤销功能、快照不可变数据、时间旅行调试
解释器定义语言文法表示配置文件解析、DSL、SQL 解析解析器组合子、PEG

设计模式精选:函数式视角

随着函数式编程思想在主流语言中的普及,许多经典设计模式的存在形式发生了本质变化。一些模式被语言特性直接吸收,一些模式在高阶函数和不可变数据面前显得多余,还有一些模式则以新的面貌继续发挥作用。

模式的本质是语言缺陷的补丁

设计模式的诞生背景是 C++ 和 Java 这类早期 OOP 语言的局限性:缺乏一等函数、缺乏模式匹配、缺乏不可变数据、缺乏类型推导。当语言本身提供了这些能力后,很多模式就不再需要显式实现。

经典模式函数式替代方案本质转变
策略模式一等函数传参从"对象包装函数"到"函数直接传递"
命令模式一等函数从"命令对象"到"闭包"
模板方法高阶函数从"继承重写"到"函数组合"
装饰器函数组合从"包装类"到f ∘ g
迭代器惰性序列/for 推导从"迭代器对象"到"惰性求值"
责任链函数管道从"链式对象"到pipe(f1, f2, f3)
适配器函数包装器从"适配器类"到"λx. f(g(x))"
访问者模式匹配从"双重分发"到"match { case... }"

2026 年仍然值得关注的模式

并非所有模式都消失了。以下模式在现代开发中依然重要,只是实现方式更简洁。

观察者模式/响应式:Vue 和 React 的响应式系统本质是观察者模式的自动化实现,但开发者无需手动维护订阅列表。Signals(如 Preact Solid)将这一模式进一步推向声明式。

依赖注入:本质是工厂模式、策略模式和代理模式的组合。现代 DI 容器(如 Spring、.NET Core)通过类型推导和装饰器实现了极简的使用体验。

状态机:XState 等库将状态模式推向新高度,配合 TypeScript 的类型推导,可以做到状态转换的编译期检查。

组合模式:React/Vue 的组件树是组合模式的应用,配合函数式组件和 hooks,实现方式比传统的 OOP 更加简洁。

中间件模式:Express、Koa、Redux 的中间件本质是装饰器模式和责任链模式的结合,通过函数链式调用实现。

构建器模式:数据类(data class)、命名参数、解构赋值等语言特性使得构建复杂对象不再需要繁琐的 Builder 类。

被时代淘汰的模式

以下模式在函数式编程背景下逐渐淡出:简单工厂/工厂方法/抽象工厂被依赖注入容器接管、模块化系统提供了天然的工厂机制;迭代器被 for 推导、惰性序列、数组方法取代;模板方法被高阶函数和组合取代;访问者被模式匹配和代数数据类型取代;备忘录被不可变数据结构取代,天然支持时间旅行调试。

反模式

反模式是指那些看似合理但实际上会导致负面效果的设计或实践。识别反模式比学习正面模式同样重要。

架构层面的反模式

反模式名称表现特征负面影响正确做法
大泥球缺乏清晰结构,代码纠缠在一起难以维护、难以测试按业务领域划分模块,建立清晰边界
面条代码控制流混乱,大量 goto 或深层嵌套难以理解、容易出错使用结构化编程,提取函数,提前返回
黄金锤用一种技术解决所有问题技术选型不当,过度设计根据问题特性选择合适工具
造轮子重复实现已有功能浪费时间、质量不如成熟方案优先使用成熟库和框架

面向对象特有的反模式

反模式名称表现特征负面影响正确做法
上帝对象一个类承担过多职责难以理解、难以测试、难以维护单一职责原则,拆分职责
贫血模型领域对象只有数据没有行为业务逻辑散落,丢失 OOP 优势充血模型,行为与数据绑定
紧耦合类之间依赖关系复杂改一处牵动全身依赖倒置,面向接口编程
滥用继承为复用代码而继承层次过深,脆弱基类问题组合优于继承
循环依赖A 依赖 B,B 依赖 A编译失败、初始化困难重新设计模块边界,引入中间层
单例滥用到处使用单例隐式依赖、难以测试、全局状态依赖注入,限定作用域

代码层面的反模式

魔法数字:直接使用未命名常量,用命名常量或枚举替代。

过长参数列表:函数参数超过 5 个,使用参数对象或选项模式。

深层嵌套:缩进层级过深,使用提前返回和提取函数。

重复代码:相同逻辑出现多次,提取函数或模板。

过早优化:在未确认性能瓶颈前优化,先测量再优化。

注释掉代码:保留注释掉的旧代码,用版本控制管理历史。

捕获所有异常:空的 catch 块或捕获 Exception,精确捕获可处理的异常。