设计模式:可复用面向对象软件的基础
软件设计模式领域的开山之作,由 GoF(四人组)撰写。本书系统总结了 23 种经典设计模式,分为创建型、结构型、行为型三大类。每种模式都包含问题描述、解决方案、适用场景、后果分析等完整内容。本书提出了"针对接口编程而非实现编程"、"优先使用对象组合而非继承"等经典设计原则,是面向对象软件设计的必读经典。
本书速读
📖 本书核心内容
《设计模式:可复用面向对象软件的基础》是软件设计模式领域的开山之作,首次出版于 1994 年。由 Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides 四人(简称 GoF)撰写。本书系统总结了 23 种经典设计模式,分为创建型、结构型、行为型三大类。
本书提出了"针对接口编程而非实现编程"、"优先使用对象组合而非继承"等经典设计原则。这些原则至今仍是面向对象软件设计的基石。GoF 的贡献不仅在于总结了 23 种模式,更在于建立了一种设计模式的描述语言——每种模式都包含问题描述、解决方案、适用场景、后果分析,使设计模式成为可交流、可复用的知识。
🎯 核心模块一:创建型模式——对象实例化的艺术
创建型模式关注对象的创建机制,解决"如何创建对象"的问题。GoF 总结了 5 种创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。这些模式的核心思想是:将对象的创建与使用分离,使系统不依赖于对象的具体类。
单例模式确保一个类只有一个实例,并提供全局访问点。它适用于配置管理器、日志管理器、数据库连接池等需要全局唯一实例的场景。但单例模式也有争议——它本质上是一个全局变量,会引入隐式依赖,使测试变得困难。现代实践中,依赖注入框架(如 Spring、Guice)往往能更好地解决全局唯一实例的问题。
工厂方法模式定义一个创建对象的接口,让子类决定实例化哪个类。它适用于框架需要创建对象但不知道具体类型的场景。抽象工厂模式提供创建一系列相关或依赖对象的接口,无需指定具体类。它适用于需要创建产品族(如不同操作系统的 UI 组件)的场景。建造者模式将复杂对象的构建与表示分离,使同样的构建过程可以创建不同的表示。它适用于对象构建步骤复杂、需要灵活组合的场景。原型模式用原型实例指定创建对象的种类,并通过拷贝这些原型创建新对象。它适用于对象创建成本高、需要频繁复制的场景。
创建型模式的选择取决于具体场景。如果只需要一个实例,考虑单例模式;如果创建逻辑需要封装,考虑工厂方法;如果需要创建产品族,考虑抽象工厂;如果构建过程复杂,考虑建造者;如果需要频繁复制,考虑原型。理解每种模式的本质而非死记硬背,才能在实际项目中灵活运用。
🎯 核心模块二:结构型模式——对象组合的智慧
结构型模式关注对象之间的组合关系,解决"如何组织对象"的问题。GoF 总结了 7 种结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。这些模式的核心思想是:通过对象组合而非类继承来构建灵活的系统。
适配器模式将一个类的接口转换成客户希望的另一个接口。它适用于需要使用现有类但接口不匹配的场景。装饰器模式动态地给对象添加额外职责。它适用于需要灵活扩展功能而非通过继承的场景。代理模式为其他对象提供一个代理以控制对这个对象的访问。它适用于远程代理、虚拟代理、保护代理等场景。外观模式为子系统中的一组接口提供一个一致的界面。它适用于需要简化复杂子系统接口的场景。
桥接模式将抽象部分与实现部分分离,使它们可以独立变化。它适用于抽象和实现都需要扩展的场景。组合模式将对象组合成树形结构以表示"部分-整体"的层次结构。它适用于需要统一处理单个对象和组合对象的场景。享元模式运用共享技术有效地支持大量细粒度对象。它适用于大量相似对象导致内存开销过大的场景。
结构型模式体现了"优先使用对象组合而非继承"的设计原则。继承是编译时的静态关系,组合是运行时的动态关系。组合比继承更灵活,因为可以在运行时改变组合的对象。但组合也不是万能的——过度使用组合会导致系统中存在大量小对象,增加系统的复杂性。关键在于找到平衡:用继承建立类型层次,用组合实现功能扩展。
🎯 核心模块三:行为型模式——对象交互的策略
行为型模式关注对象之间的交互和责任分配,解决"如何分配职责"的问题。GoF 总结了 11 种行为型模式:策略模式、观察者模式、模板方法模式、命令模式、状态模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式、责任链模式。这些模式的核心思想是:将行为封装为对象,使行为可以独立于使用它的对象而变化。
策略模式定义一系列算法,将每个算法封装起来,使它们可以互相替换。它适用于需要在运行时切换算法的场景。观察者模式定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖对象都会收到通知。它适用于事件处理系统、MVC 架构等场景。模板方法模式定义一个算法的骨架,将一些步骤延迟到子类中实现。它适用于算法骨架固定但具体步骤可变的场景。命令模式将请求封装为对象,使可以用不同的请求参数化其他对象。它适用于需要支持撤销/重做、队列请求、日志请求的场景。
状态模式允许对象在其内部状态改变时改变其行为。它适用于对象行为随状态变化而变化的场景。中介者模式定义一个中介对象来封装一系列对象之间的交互。它适用于对象之间交互复杂、需要解耦的场景。迭代器模式提供一种方法顺序访问聚合对象中的各个元素。它适用于需要遍历集合但不暴露内部表示的场景。访问者模式表示一个作用于某对象结构中的各元素的操作。它适用于需要对对象结构中的元素执行多种操作且不想修改元素类的场景。
行为型模式体现了"封装变化点"的设计思想。策略模式封装算法的变化,观察者模式封装依赖关系的变化,命令模式封装请求的变化,状态模式封装状态的变化。通过封装变化点,系统可以在不影响其他部分的情况下修改某个行为。这是面向对象设计的核心思想——将变化隔离,使系统更容易维护和扩展。
⭐ 金句摘录
"针对接口编程,而不是针对实现编程。"
"优先使用对象组合,而不是类继承。"
"封装变化点,用接口隔离变化。"
"设计模式不是银弹,但它们是经验的结晶。"
"好的设计不是预先规划出来的,而是在实践中逐步演化出来的。"
📚 阅读建议
适合有面向对象编程经验的开发者,先了解设计原则再逐个学习设计模式,配合实际项目实践效果最佳。