设计模式
约 2243 字大约 7 分钟
2020-09-06
快速查阅 GoF 23 种设计模式的 UML 类图、核心思想与应用场景。
背景与动机
设计模式是软件开发中经过验证的解决方案模板。当你遇到特定场景的设计难题时,设计模式能提供一套可复用的架构思路。
本文适合有一定面向对象基础的开发者,用于快速查阅各模式的类图结构和核心要点。
设计模式分类
根据 GoF 的经典分类,设计模式分为三大类:
| 分类 | 核心关注点 | 包含模式 |
|---|---|---|
| 创建型 | 对象创建过程 | 单例、工厂、抽象工厂、生成器、原型 |
| 结构型 | 类与对象的组合 | 适配器、桥接、组合、装饰器、外观、享元、代理 |
| 行为型 | 对象间的职责分配 | 策略、模板方法、观察者、迭代器、责任链、命令、备忘录、状态、访问者、中介者、解释器 |
本文按"结构型 → 行为型 → 创建型"顺序展开,因为结构型和行为型在实际项目中使用频率更高。
软件开发原则
设计模式的核心思想是遵循 SOLID 原则:
- 单一职责:一个类只做一件事
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换:子类可以替换父类
- 接口隔离:接口职责单一
- 依赖倒置:依赖抽象而非实现
详细内容参考:设计原则 PDF(在新窗口打开)
结构型模式
外观模式(Facade)
核心思想:为子系统中的一组接口提供统一的高层接口,简化客户端调用。
生活类比:通过村长管理村民——你只需和村长打交道,不用分别联系每位村民。
应用场景:
- 复杂子系统需要简化接口
- 分层架构中为每层提供统一入口
- 遗留系统的重构封装
适配器模式(Adapter)
核心思想:将一个类的接口转换成客户端期望的另一个接口,解决接口不兼容问题。
生活类比:通过邮差联系村长——邮差作为中介,帮你和另一个系统的村长通信。
应用场景:
- 新旧系统接口对接
- 第三方库接口不兼容
- 复用现有类但接口不匹配
桥接模式(Bridge)
核心思想:将抽象部分与实现部分分离,使它们可以独立变化。
生活类比:通过村长职位锁定村长——职位(抽象)和人选(实现)可以独立更换。
应用场景:
- 跨平台 UI 组件(不同平台渲染 + 不同样式主题)
- JDBC 驱动(统一接口 + 不同数据库实现)
- 多维度变化的业务场景
装饰器模式(Decorator)
核心思想:动态地给对象添加额外职责,比继承更灵活。
生活类比:通过衣服装饰村民——基础是人,衣服是装饰,可以叠加多件衣服。
应用场景:
- Java I/O 流(
BufferedReader装饰FileReader) - 咖啡店订单系统(基础咖啡 + 多种调料)
- 动态扩展功能且不影响其他对象
组合模式(Composite)
核心思想:将对象组合成树形结构以表示"部分-整体"层次,使客户端统一对待单个对象和组合对象。
生活类比:县乡村一级一级的管理方式——县管乡、乡管村,形成树形层级结构。
应用场景:
- 文件系统(文件夹和文件的树形结构)
- 组织架构管理
- GUI 组件树(窗口、面板、按钮)
行为型模式
享元模式(Flyweight)
核心思想:运用共享技术有效支持大量细粒度对象,减少内存占用。
生活类比:将军事、政治、外交共享智囊团出方案——多个部门共用同一批专家,避免各自组建团队。
应用场景:
- 字符串常量池(String Pool)
- 线程池、连接池
- 大量重复对象的场景(如游戏中的棋子、粒子)
代理模式(Proxy)
核心思想:为其他对象提供代理以控制对该对象的访问。
生活类比:将财政、军事、政务、法务交给各部长管理——国王通过部长间接管理各领域事务。
代理类型:
- 远程代理:为远程对象提供本地代理(RPC 调用)
- 虚拟代理:延迟创建开销大的对象(图片懒加载)
- 保护代理:控制访问权限
- 智能代理:添加额外逻辑(引用计数、日志)
应用场景:
- Spring AOP(动态代理)
- MyBatis Mapper 代理
- 网络请求拦截
策略模式(Strategy)
核心思想:定义一系列算法,把它们封装起来,并使它们可以相互替换。
生活类比:出行方式可选驾车、公交、骑行——目的地相同,但策略可以灵活切换。
应用场景:
- 支付方式选择(微信、支付宝、银行卡)
- 排序算法切换
- 数据压缩方式选择
创建型模式
生成器模式(Builder)
核心思想:将复杂对象的构建与表示分离,使同样的构建过程可以创建不同的表示。
生活类比:将汽车由部件组装,而不需要管部件内部零件的组装过程。
应用场景:
- 复杂对象有多个可选属性(如
StringBuilder、Lombok @Builder) - 分步创建对象
- 创建过程稳定但配置多变
总结
设计模式不是银弹,不要为了用模式而用模式。核心原则:
- 优先组合而非继承:组合更灵活
- 针对接口编程:降低耦合
- 开闭原则:扩展开放,修改关闭
当遇到实际设计问题时,先识别场景,再选择合适的模式。过度设计反而增加复杂度。
参考资源
- java-design-patterns(GitHub) - Java 实现的 23 种设计模式完整示例
- 《设计模式:可复用面向对象软件的基础》- GoF 经典著作
- 《Head First 设计模式》- 图文并茂的入门书籍
