🎉 设计模式学习之旅圆满完成!

经过23篇详细的文章,我们完整地学习了GOF(Gang of Four)提出的23种经典设计模式。从创建型到结构型,再到行为型,每一种模式都为我们提供了解决特定问题的优雅方案。

让我们一起回顾这段精彩的学习之旅,并从更高的视角来理解和比较这些设计模式。

📚 全面回顾:23种设计模式概览

🏗️ 创建型模式(Creational Patterns)

核心思想:封装对象的创建过程,使系统独立于对象的创建、组合和表示方式。

模式核心作用关键特点适用场景
单例模式
Singleton
确保类只有一个实例全局访问点、延迟初始化配置管理、日志记录、数据库连接池
工厂方法模式
Factory Method
创建对象的接口,由子类决定实例化类型多态创建、产品族扩展UI组件创建、数据库驱动选择
抽象工厂模式
Abstract Factory
创建相关对象家族产品族一致性、平台无关性跨平台UI、主题切换
建造者模式
Builder
分步骤构建复杂对象链式调用、参数可选复杂配置对象、SQL查询构建
原型模式
Prototype
通过克隆创建对象深拷贝、性能优化对象模板、游戏角色复制

🏛️ 结构型模式(Structural Patterns)

核心思想:处理类与对象的组合,形成更大的结构,同时保持结构的灵活性和高效性。

模式核心作用关键特点适用场景
适配器模式
Adapter
使不兼容接口协同工作接口转换、兼容性第三方库集成、遗留系统改造
桥接模式
Bridge
分离抽象与实现双维度扩展、平台无关图形绘制、设备驱动
组合模式
Composite
树形结构的统一处理整体-部分层次、递归结构文件系统、UI组件树
装饰器模式
Decorator
动态添加对象功能功能叠加、运行时扩展流处理、权限控制
外观模式
Facade
简化复杂子系统接口统一入口、降低耦合API封装、框架设计
享元模式
Flyweight
高效支持大量小粒度对象内外状态分离、内存优化文本编辑器、游戏粒子系统
代理模式
Proxy
控制对象的访问延迟加载、访问控制远程调用、缓存、权限控制

🎭 行为型模式(Behavioral Patterns)

核心思想:关注对象间的通信和职责分配,使对象间的交互更加灵活。

模式核心作用关键特点适用场景
责任链模式
Chain of Responsibility
请求沿处理链传递动态链构建、处理解耦审批流程、异常处理
命令模式
Command
封装请求为对象请求参数化、撤销重做操作记录、宏命令
解释器模式
Interpreter
定义语言文法和解释器文法规则、递归解释DSL、表达式计算
迭代器模式
Iterator
顺序访问聚合对象元素统一遍历接口、多种遍历方式集合遍历、数据流处理
中介者模式
Mediator
封装对象间的交互集中控制、解耦通信聊天室、UI组件交互
备忘录模式
Memento
保存和恢复对象状态状态快照、封装保护撤销功能、游戏存档
观察者模式
Observer
对象状态变化的通知机制发布订阅、松耦合事件系统、MVC架构
状态模式
State
状态改变时改变行为状态封装、行为切换状态机、工作流
策略模式
Strategy
封装算法族并可互换算法独立、运行时切换排序算法、支付方式
模板方法模式
Template Method
定义算法骨架公共流程、子类定制框架设计、算法模板
访问者模式
Visitor
在不修改类的前提下扩展功能操作与数据分离、双分派编译器、文档处理

🎯 设计模式选择指南

根据问题类型选择模式

🔨 对象创建问题

1
2
3
4
5
需要控制实例数量?           → 单例模式
需要根据条件创建不同对象?    → 工厂方法模式
需要创建相关对象家族?       → 抽象工厂模式
需要分步骤构建复杂对象?     → 建造者模式
需要基于现有对象创建新对象?  → 原型模式

🏗️ 对象组合问题

1
2
3
4
5
6
7
需要适配不兼容的接口?       → 适配器模式
需要分离抽象和实现?        → 桥接模式
需要处理树形结构?          → 组合模式
需要动态添加功能?          → 装饰器模式
需要简化复杂系统接口?      → 外观模式
需要节省内存使用?          → 享元模式
需要控制对象访问?          → 代理模式

🎪 对象交互问题

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
需要处理请求链?            → 责任链模式
需要封装操作请求?          → 命令模式
需要解释自定义语言?        → 解释器模式
需要遍历聚合对象?          → 迭代器模式
需要协调对象间交互?        → 中介者模式
需要保存和恢复状态?        → 备忘录模式
需要通知状态变化?          → 观察者模式
需要根据状态改变行为?      → 状态模式
需要在运行时选择算法?      → 策略模式
需要定义算法模板?          → 模板方法模式
需要在不修改类的情况下增加操作? → 访问者模式

📊 设计模式对比分析

🔄 相似模式对比

策略模式 vs 状态模式 vs 命令模式

维度策略模式状态模式命令模式
目的选择算法管理状态转换封装请求
结构平行算法族状态转换图命令对象
切换方式外部主动切换内部自动切换不涉及切换
关注点算法的选择状态的管理操作的记录

工厂方法 vs 抽象工厂 vs 建造者

维度工厂方法抽象工厂建造者
复杂度简单对象对象家族复杂对象
扩展性新产品类型新产品族新构建步骤
使用方式一次性创建批量创建分步骤创建
关注点创建什么创建哪一族如何创建

装饰器 vs 适配器 vs 代理

维度装饰器适配器代理
目的增强功能接口转换控制访问
对象关系包装增强接口适配替身代理
使用时机运行时动态设计时静态透明使用
功能变化功能增加接口改变访问控制

观察者 vs 发布-订阅 vs 中介者

维度观察者发布-订阅中介者
耦合度低耦合完全解耦星形耦合
通信方式直接通知消息中间件集中协调
复杂度简单中等较复杂
适用场景简单事件分布式系统复杂交互

🎨 模式组合使用

实际项目中,设计模式往往不是孤立使用的,而是相互组合:

经典组合1:MVC架构

1
2
3
Model(模型)      ← 观察者模式 → View(视图)
   ↑                                ↓
   └── 策略模式 ←→ Controller(控制器)

经典组合2:GUI框架

1
2
3
4
5
抽象工厂(创建组件族)
组合模式(组件树) + 装饰器(功能增强)
观察者模式(事件处理) + 命令模式(操作封装)

经典组合3:游戏引擎

1
2
3
4
5
6
7
单例模式(游戏管理器)
工厂方法(角色创建) + 原型模式(角色复制)
状态模式(AI行为) + 策略模式(技能选择)
备忘录模式(存档系统) + 观察者模式(事件系统)

🏆 设计模式最佳实践

✅ 正确使用原则

1. 不要过度设计

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ❌ 错误:简单问题复杂化
class SimpleCalculator {
    // 为简单加法使用策略模式是过度设计
    private CalculationStrategy strategy;
}

// ✅ 正确:简单问题简单解决
class SimpleCalculator {
    public int add(int a, int b) {
        return a + b;
    }
}

2. 先有问题,再用模式

1
2
3
4
5
6
7
8
9
// ✅ 正确的思路:
// 1. 识别问题:需要根据不同类型创建不同对象
// 2. 选择模式:工厂方法模式适合这个问题
// 3. 实现模式:编写具体的工厂类

// ❌ 错误的思路:
// 1. 想用某个模式
// 2. 强行套用到代码中
// 3. 代码变得复杂难懂

3. 理解模式本质,而非死记硬背

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 理解单例模式的本质:控制实例数量
// 不仅可以实现"只有一个实例"
// 也可以实现"最多N个实例"

class ConnectionPool {
    private static final int MAX_CONNECTIONS = 10;
    private static final List<Connection> pool = new ArrayList<>();

    // 这也是单例模式思想的应用
}

🎯 选择模式的决策树

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
遇到设计问题时:

1. 这是创建对象的问题吗?
   ├─ 是 → 考虑创建型模式
   │   ├─ 需要控制实例数量? → 单例模式
   │   ├─ 需要根据条件创建? → 工厂方法模式
   │   ├─ 需要创建对象家族? → 抽象工厂模式
   │   ├─ 需要分步构建? → 建造者模式
   │   └─ 需要复制对象? → 原型模式
   └─ 否 → 继续判断

2. 这是对象结构的问题吗?
   ├─ 是 → 考虑结构型模式
   │   ├─ 接口不兼容? → 适配器模式
   │   ├─ 需要分离抽象实现? → 桥接模式
   │   ├─ 树形结构? → 组合模式
   │   ├─ 动态增加功能? → 装饰器模式
   │   ├─ 简化复杂接口? → 外观模式
   │   ├─ 内存优化? → 享元模式
   │   └─ 控制访问? → 代理模式
   └─ 否 → 考虑行为型模式

3. 这是对象交互的问题吗?
   └─ 是 → 根据具体交互方式选择行为型模式

🚀 现代框架中的设计模式

Spring框架中的设计模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 单例模式:Spring Bean默认是单例
@Component
public class UserService { }

// 工厂方法模式:BeanFactory
@Bean
public DataSource dataSource() {
    return new HikariDataSource();
}

// 代理模式:AOP
@Transactional
public void saveUser(User user) { }

// 观察者模式:事件监听
@EventListener
public void handleUserCreated(UserCreatedEvent event) { }

// 模板方法模式:JdbcTemplate
jdbcTemplate.query(sql, rowMapper);

React/Vue中的设计模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 观察者模式:状态管理
const [state, setState] = useState(initialState);

// 组合模式:组件树
function App() {
    return (
        <Layout>
            <Header />
            <Content>
                <UserList />
            </Content>
        </Layout>
    );
}

// 策略模式:条件渲染
const renderContent = () => {
    switch(viewType) {
        case 'list': return <ListView />;
        case 'grid': return <GridView />;
        default: return <DefaultView />;
    }
};

// 装饰器模式:高阶组件
const withAuth = (Component) => {
    return (props) => {
        if (!isAuthenticated) return <Login />;
        return <Component {...props} />;
    };
};

💡 设计模式学习建议

📖 学习路径推荐

1. 入门阶段(必须掌握)

  • 单例模式 - 最简单,理解设计模式思想
  • 工厂方法模式 - 理解创建与使用分离
  • 观察者模式 - 理解事件驱动编程
  • 策略模式 - 理解算法封装

2. 进阶阶段(重点掌握)

  • 装饰器模式 - 理解功能增强
  • 适配器模式 - 理解接口适配
  • 命令模式 - 理解操作封装
  • 状态模式 - 理解状态管理

3. 高级阶段(深入理解)

  • 抽象工厂模式 - 理解产品族
  • 建造者模式 - 理解复杂构建
  • 组合模式 - 理解树形结构
  • 访问者模式 - 理解双分派

4. 专家阶段(根据需要)

  • 其余模式根据实际需要深入学习

🎓 实践建议

1. 从重构开始

1
2
3
// 发现代码中的问题,然后应用设计模式重构
// 例如:发现大量的if-else,考虑策略模式
// 例如:发现重复的创建逻辑,考虑工厂模式

2. 阅读优秀源码

1
2
3
// Spring源码中的设计模式
// JDK源码中的设计模式
// 开源框架中的设计模式应用

3. 在项目中应用

1
2
3
// 不要为了使用模式而使用模式
// 当遇到问题时,思考哪种模式能优雅地解决
// 逐步积累使用经验

🔮 设计模式的未来

函数式编程的影响

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 传统的策略模式
class PaymentContext {
    constructor(strategy) {
        this.strategy = strategy;
    }
    pay(amount) {
        return this.strategy.pay(amount);
    }
}

// 函数式的"策略模式"
const payWithStrategy = (strategy) => (amount) => strategy(amount);
const payWithCredit = payWithStrategy((amount) => `Credit: ${amount}`);
const payWithPaypal = payWithStrategy((amount) => `PayPal: ${amount}`);

现代语言特性的影响

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Java的Lambda简化了很多模式
// 传统的观察者模式
list.addObserver(new Observer() {
    public void update(Observable o, Object arg) {
        System.out.println("Updated: " + arg);
    }
});

// Lambda简化后
list.addObserver((o, arg) -> System.out.println("Updated: " + arg));

🎉 结语:设计模式的价值

🏆 设计模式带给我们什么?

1. 通用的设计词汇

当我们说"这里用观察者模式",团队成员立即理解设计意图。

2. 经过验证的解决方案

不需要重新发明轮子,可以直接使用前人总结的最佳实践。

3. 更好的代码质量

  • 提高代码的可读性
  • 增强代码的可维护性
  • 降低系统的耦合度
  • 提升代码的复用性

4. 设计思维的提升

  • 学会从更高层次思考问题
  • 培养面向对象设计的直觉
  • 理解软件架构的本质

🎯 设计模式的核心原则

记住这些原则,比记住具体模式更重要:

1. 单一职责原则

一个类应该只有一个引起它变化的原因。

2. 开闭原则

对扩展开放,对修改关闭。

3. 里氏替换原则

子类对象应该能够替换父类对象。

4. 接口隔离原则

不应该强迫客户依赖它们不使用的方法。

5. 依赖倒置原则

高层模块不应该依赖低层模块,都应该依赖抽象。

6. 迪米特法则

一个对象应该对其他对象保持最少的了解。

7. 组合优于继承

优先使用对象组合,而不是类继承。

🌟 最后的话

设计模式不是银弹,不能解决所有问题。它们是工具,是前人智慧的结晶。关键是要:

  • 理解问题的本质
  • 选择合适的模式
  • 灵活运用,不拘泥于形式
  • 持续实践,在实战中成长

编程之路漫漫,设计模式只是其中一站。但掌握了这些模式,你已经具备了优秀软件设计师的基本素养。

愿你在编程的世界里,写出优雅、健壮、可维护的代码! 🚀


📖 系列文章索引

创建型模式

  1. 单例模式 - 全局唯一实例的优雅实现
  2. 工厂方法模式 - 创建对象的艺术
  3. 抽象工厂模式 - 产品族的创建大师
  4. 建造者模式 - 复杂对象的优雅构建
  5. 原型模式 - 对象克隆的高效之道

结构型模式

  1. 适配器模式 - 让不兼容的接口和谐共处
  2. 桥接模式 - 分离抽象与实现的艺术
  3. 组合模式 - 树形结构的统一处理
  4. 装饰器模式 - 动态扩展对象功能
  5. 外观模式 - 简化复杂系统的接口
  6. 享元模式 - 高效处理大量细粒度对象
  7. 代理模式 - 控制对象访问的智慧

行为型模式

  1. 命令模式 - 请求封装与处理的艺术
  2. 责任链模式 - 请求传递的优雅之道
  3. 观察者模式 - 让对象间的通信更优雅
  4. 策略模式 - 让算法选择更灵活
  5. 模板方法模式 - 定义算法骨架的艺术
  6. 状态模式 - 让对象状态转换更优雅
  7. 访问者模式 - 在不修改类的情况下扩展功能
  8. 中介者模式 - 让对象间交互更简洁
  9. 备忘录模式 - 优雅地保存和恢复对象状态
  10. 迭代器模式 - 优雅地遍历集合元素
  11. 解释器模式 - 为语言创建解释器

感谢您完成了这次设计模式的学习之旅!希望这些知识能在您的编程道路上发挥作用。✨