“23种设计模式”这一经典分类最早系统性地提出是在1994年出版的著作 《Design Patterns: Elements of Reusable Object-Oriented Software》(中文译名:《设计模式:可复用面向对象软件的基础》)中。该书由四位作者——Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 共同撰写,他们也因此被称为“GoF”(Gang of Four,四人组)。
大多数平常用不到,但是有些经常可见。
比如策略模式,Strategy模式其实就是把方法(策略)当作可替换的变量传进去。将“行为”作为一等公民(first-class citizen)传入,比如传一个函数、lambda 表达式或接口实现。
参见:
这23种设计模式根据其目的和作用被分为三大类:
一、创建型模式(Creational Patterns)
关注对象的创建机制,帮助系统独立于对象的创建、组合和表示方式。
- Abstract Factory(抽象工厂)
- Builder(建造者)
- Factory Method(工厂方法)
- Prototype(原型)
- Singleton(单例)
共 5 种
二、结构型模式(Structural Patterns)
处理类或对象的组合,以形成更大的结构,同时保持结构的灵活性和效率。
- Adapter(适配器)
- Bridge(桥接)
- Composite(组合)
- Decorator(装饰器)
- Facade(外观)
- Flyweight(享元)
- Proxy(代理)
共 7 种
三、行为型模式(Behavioral Patterns)
关注对象之间的职责分配和通信机制,描述对象或类之间的交互与协作。
- Chain of Responsibility(责任链)
- Command(命令)
- Interpreter(解释器)
- Iterator(迭代器)
- Mediator(中介者)
- Memento(备忘录)
- Observer(观察者)
- State(状态)
- Strategy(策略)
- Template Method(模板方法)
- Visitor(访问者)
共 11 种
总计:5 + 7 + 11 = 23 种设计模式
这些模式至今仍是面向对象软件设计中的重要参考,广泛应用于各种编程语言和框架中。
之前已经写过几种,后面慢慢补,接下来,我们看看设计模式之上,更加容易记忆的设计思想。
设计模式与设计原则区别
很多时候,我们很容易把这两类搞混,接下来做个对比。
一、设计原则 vs. 设计模式
设计原则(Design Principles)
- 基础指导思想:高层次的抽象准则
- 来源:SOLID原则、DRY、KISS等
- 数量:相对较少,约10-20条核心原则
- 作用:告诉我们为什么要这样设计
设计模式(Design Patterns)
- 具体解决方案:针对特定问题的可重用方案
- 来源:GoF的23种经典模式
- 数量:经典的23种,还有其他很多模式
- 作用:告诉我们如何实现好的设计
二、具体的分类
SOLID原则(设计原则,不是模式)
- S - 单一职责原则(SRP)
- O - 开放封闭原则(OCP)← 你提到的
- L - 里氏替换原则(LSP)
- I - 接口隔离原则(ISP)
- D - 依赖倒置原则(DIP)← 你提到的
GoF的23种模式(设计模式)
- 就是上面列出的创建型5种、结构型7种、行为型11种
- 不包括SOLID原则等设计原则
三、它们的关系:原则指导模式
设计原则(指导思想)
↓
设计模式(具体实现)
↓
具体代码
示例:如何通过模式实现原则
1. 开放封闭原则(OCP)的实现
// OCP要求:对扩展开放,对修改封闭
// ❌ 违反OCP - 需要修改现有代码
class Calculator {
public int calculate(int a, int b, String operation) {
if ("add".equals(operation)) {
return a + b;
} else if ("subtract".equals(operation)) { // 新增操作需要修改
return a - b;
}
// 每加一个操作都要改这里
throw new IllegalArgumentException();
}
}
// ✅ 通过策略模式实现OCP
interface Operation { // 抽象
int execute(int a, int b);
}
class AddOperation implements Operation {
@Override
public int execute(int a, int b) { return a + b; }
}
class SubtractOperation implements Operation {
@Override
public int execute(int a, int b) { return a - b; }
}
class Calculator {
private Operation operation;
public Calculator(Operation operation) {
this.operation = operation;
}
public int calculate(int a, int b) {
return operation.execute(a, b); // 核心代码不修改
}
}
// 扩展:新增乘法操作,Calculator类不需要修改
class MultiplyOperation implements Operation { // 扩展开放
@Override
public int execute(int a, int b) { return a * b; }
}
2. 依赖倒置原则(DIP)的实现
// DIP要求:高层模块不依赖低层模块,都依赖抽象
// ❌ 违反DIP - 高层直接依赖低层
class UserService { // 高层模块
private MySQLDatabase db; // 直接依赖具体实现
public void saveUser(User user) {
db.save(user); // 紧密耦合
}
}
// ✅ 通过依赖注入+接口实现DIP
interface Database { // 抽象接口
void save(Object data);
}
class MySQLDatabase implements Database { // 低层模块
@Override
public void save(Object data) { /* MySQL实现 */ }
}
class UserService { // 高层模块
private Database db; // 依赖抽象
public UserService(Database db) { // 依赖注入
this.db = db;
}
public void saveUser(User user) {
db.save(user); // 通过抽象调用
}
}
// 可以轻松替换数据库实现
class PostgresDatabase implements Database { // 新的低层模块
@Override
public void save(Object data) { /* Postgres实现 */ }
}
// 使用
UserService service = new UserService(new PostgresDatabase());
四、表格速览
| 维度 | 设计原则 | 设计模式 |
|---|---|---|
| 性质 | 指导思想、哲学 | 具体方案、模板 |
| 示例 | SOLID原则、DRY、KISS | 单例、工厂、策略、观察者 |
| 关系 | 模式遵循原则 | 模式实现原则 |
| 抽象级别 | 更高层、更抽象 | 较具体、可落地 |
| 数量 | 较少(核心约10个) | 较多(GoF 23个 + 其他) |
五、完整的软件设计知识体系
软件开发哲学(最顶层)
↓
设计原则(如SOLID、DRY、KISS、YAGNI) ← 你的问题
↓
设计模式(GoF 23种 + 其他模式) ← 你之前列的
↓
架构模式(MVC、微服务、事件驱动等)
↓
具体实现技术
六、为什么容易混淆?
- 都有"模式"二字:原则、模式、架构模式
- 密切关联:设计模式通常实现设计原则
- 概念嵌套:例如,工厂模式体现了依赖倒置原则
关键点:
- 比如,开放封闭原则(OCP)和依赖倒置原则(DIP)是设计原则
- 策略模式、工厂模式等是设计模式
- 模式是实现原则的具体手段
能区分这两者说明对软件设计的理解已经很深入了。