在软件开发中,前人对软件系统的设计和开发总结了一些原则和模式。不管用什么语言做开发,它们都将对系统设计和开发提供指导意义。本系列将逐一展开 24 种设计模式(GoF 23 + 简单工厂)和 7 个设计原则。
7 个设计原则
| 原则 | 英文 | 一句话概括 |
|---|---|---|
| 单一职责原则 | SINGLE RESPONSIBILITY PRINCIPLE | 一个类负责一项职责 |
| 里氏替换原则 | LISKOV SUBSTITUTION PRINCIPLE | 继承与派生的规则:子类对象必须能替换掉所有父类对象 |
| 依赖倒置原则 | DEPENDENCE INVERSION PRINCIPLE | 高层模块不应依赖低层模块,二者都依赖抽象;针对接口编程,不针对实现编程 |
| 接口隔离原则 | INTERFACE SEGREGATION PRINCIPLE | 建立单一接口,不要建立庞大臃肿的接口,接口中的方法尽量少 |
| 迪米特法则 | LAW OF DEMETER | 低耦合,高内聚 |
| 开闭原则 | OPEN CLOSE PRINCIPLE | 一个软件实体(类、模块、函数)应该对扩展开放,对修改关闭 |
| 组合/聚合复用原则 | CARP | 尽量使用组合和聚合,少使用继承来达到复用 |
详细的阐述见 SOLID 设计原则。
24 大设计模式
创建型模式(6 种)
对象创建的过程封装,让创建过程更灵活可控:
| 模式 | 说明 | 文章 |
|---|---|---|
| 简单工厂 | 把实例化操作单独放到一个类中,由工厂类决定用哪个具体子类实例化,将客户类与具体子类解耦 | 阅读 |
| 工厂方法 | 定义一个创建对象的接口,由子类决定要实例化哪个类,把实例化操作推迟到子类 | 阅读 |
| 抽象工厂 | 创建的是对象家族(很多相关对象必须一起创建),而不只是一个对象 | 阅读 |
| 生成器 | 封装一个对象的构造过程,允许按步骤构造 | 阅读 |
| 原型模式 | 使用原型实例指定要创建对象的类型,通过复制这个原型来创建新对象 | 阅读 |
| 单例模式 | 确保一个类只有一个实例,并提供该实例的全局访问点(本文介绍 6 种常用实现方式) | 阅读 |
结构型模式(7 种)
类和对象的组合,让结构更清晰:
| 模式 | 说明 | 文章 |
|---|---|---|
| 适配器 | 将一个类的接口转换成客户期望的另一个接口;对象适配器使用组合,类适配器使用多重继承 | 阅读 |
| 桥接 | 将实现和抽象放在两个不同的类层次中,使它们可以独立改变 | 阅读 |
| 组合 | 将对象组合成树形结构表现”整体/部分”层次,让客户以一致的方式处理个别对象和对象组合 | 阅读 |
| 装饰 | 动态地将责任附加到对象上,比继承更有弹性的扩展方式 | 阅读 |
| 外观 | 提供一个统一的接口访问子系统中的一群接口,让子系统更容易使用 | 阅读 |
| 享元 | 利用共享方式支持大量细粒度对象,让某个类的一个实例提供许多”虚拟实例” | 阅读 |
| 代理 | 为另一个对象提供一个替身或占位符,以控制对这个对象的访问 | 阅读 |
行为型模式(11 种)
对象间的通信与职责分配:
| 模式 | 说明 | 文章 |
|---|---|---|
| 责任链 | 为某个请求创建一个对象链,每个对象依序检查此请求并处理或传给下一个对象 | 阅读 |
| 命令模式 | 将”请求”封装成对象,以便使用不同的请求、队列或日志来参数化其他对象;支持可撤销操作 | 阅读 |
| 解释器 | 为语言创建解释器,通常由语言的语法和语法分析来定义 | 阅读 |
| 迭代器 | 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示 | 阅读 |
| 中介者 | 集中相关对象之间复杂的沟通和控制方式 | 阅读 |
| 备忘录 | 让对象返回之前的状态(例如用户请求”撤销”) | 阅读 |
| 观察者 | 在对象之间定义一对多的依赖,当一个对象改变状态,依赖它的对象都会收到通知并自动更新 | 阅读 |
| 状态 | 允许对象在内部状态改变时改变它的行为,对象看起来好像改了它的类 | 阅读 |
| 策略 | 定义算法族分别封装起来,让它们之间可以互相替换,算法的变化独立于使用算法的客户 | 阅读 |
| 模板方法 | 在一个方法中定义算法骨架,将一些步骤延迟到子类;子类不改变算法结构即可重定义某些步骤 | 阅读 |
| 访问者 | 为一个对象组合增加新的能力,且封装并不重要时使用 | 阅读 |
建议阅读路径
- 先读 SOLID 设计原则建立框架
- 按 创建型 → 结构型 → 行为型 的顺序逐个学习
- 结合 JDK 源码对照理解(如
java.lang.Runtime是单例、java.util.Iterator是迭代器、InputStream体系是装饰器)