设计模式
2026年1月2日约 2653 字大约 9 分钟
设计模式
1. 面向对象的设计原则(SOLID)
1.1 单一职责原则(Single Responsibility Principle, SRP)
- 简介:一个类只负责一个功能领域中的相应职责(避免混乱)
- 定义:单一职责原则要求类应该只有一个设计目的
1.2 开闭原则(Open Closed Principle,OCP)
- 简介:对扩展开放,对修改关闭(提高系统的扩展性、稳定性)
- 定义:可扩展系统并提供新行为,通过添加抽象层实现,是其他原则的基础。对扩展开放对修改封闭
1.3 里氏替换原则(Liskov Substitution Principle,LSP)
- 简介:所有引用基类的地方必须能透明地使用其子类的对象(子类可完全替换父类)
- 定义:软件实体使用基类对象时适用于子类对象,设计时应将变化类设计为抽象类或接口
1.4 接口隔离原则(Interface Segregation Principle,ISP)
- 简介:类之间的依赖关系应该建立在最小的接口上(使用多个具体接口,避免接口冗余)
- 定义:分逻辑和狭义两种理解,前者将接口视为角色,后者要求接口提供客户端需要的行为,将大接口方法分至小接口
1.5 依赖倒转原则(Dependency Inversion Principle,DIP)
- 简介:依赖于抽象,不能依赖于具体实现
- 定义:抽象不依赖于细节,针对接口编程,是实现开闭原则的主要机制,与各种技术和框架相关
1.6 合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)
- 简介:尽量使用合成/聚合,而不是通过继承达到复用的目的(减少继承带来的紧耦合,提高灵活性)
- 定义:通过组合或聚合关系复用已有对象,比继承更灵活,耦合度低。
1.7 最少知识原则(Least Knowledge Principle,LKP)或者迪米特法则(Law of Demeter,LOD)
- 简介:一个软件实体应当尽可能少的与其他实体发生相互作用(减少复杂度)
- 定义:软件实体应尽量少与其他实体相互作用,分狭义和广义原则,狭义降低类耦合但可能影响通信效率,广义主要控制信息相关方面,利于子系统解耦和复用
2. 设计模型分类
可以按两个准则来分类:
- 按目的划分:创建型、结构型、行为型
- 按范围划分:类设计模式、对象设计模式
3. 创建型模式
这类模式提供创建对象的机制,将 “对象的创建” 从具体使用中解耦,能够提升已有代码的灵活性和可复用性。
3.1 工厂方法(Factory Method)
动态生产对象
- 要点:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行
- 特点:父类负责抽象,子类负责具体实现,实现解耦的创建与使用
- 场景:多种类型商品不同接口、统一发奖服务
3.2 抽象工厂方法(Abstract Factory Method)
生产成系列对象
- 要点:提供一个 创建一系列 相关或相互依赖对象的接口,而无需制定他们具体的类
- 特点:创建一系列相关产品,用于创建一个产品家族
- 场景:代理类抽象场景
3.3 建造器(Builder)
复杂对象构造
- 要点:将一个 复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示
- 特点:适合 对象属性多,构建步骤复杂 的场景
- 场景:套餐选配、各项装修物料组合
3.4 原型(Prototype)
克隆对象
- 要点:用原型实例指定创建对象的种类,并且**通过拷贝这些原型创建新的对象**
- 特点:允许对象在不了解要创建对象的确切类以及如何创建等细节的情况下创建自定义对象
3.5 单例(Singleton)
单实例
- 要点:保证一个类仅有一个实例,并提供一个访问它的全局访问点
- 特点:
4. 结构型模式
这类模式介绍如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效。
4.1 适配器(Adapter)
转换接口
- 要点:将一个类的接口转换成客户希望的另外一个接口
- 特点:使原本不相容的接口得以协同工作
4.2 桥接(Bridge)
继承树拆分
- 要点:将 抽象接口与实现分离,使它们都可以独立的变化
- 特点:
4.3 组合(Composite)
树形目录结构
- 要点:将对象组合成树形结构,以表示 “部分-整体” 的层次结构
- 特点:使得用户对单个对象和组合对象的使用具有 一致性
4.4 装饰器(Decorator)
动态附加职责
- 要点:灵活动态 地为一个对象 添加 一些额外的功能
- 特点:
- 避免大量子类产生类膨胀,不改变原有对象结构,有效控制类的增长
- 比派生一个子类更灵活,可以在运行时按需组合功能,而不必通过大量子类来静态扩展
4.5 外观(Facade)
动态统一接口
- 要点:为子系统中的一组接口提供一个一致的界面,提供一个统一的高层接口
- 特点:
- 为系统提供统一的对外接口,简化调用(相当于一个黑箱)
- 提高了一致性和可移植性,降低了调用性能
4.6 享元(Flyweight)
汉字编码
- 要点:运用 共享 技术 有效地支持大量细粒度的对象
- 特点:提供支持大量细粒度对象共享的有效方法
4.7 代理(Proxy)
快捷方式
- 要点:为其他对象提供一种代理 以控制对这个对象的访问
- 特点:用于 控制访问对象的方式
- 场景:远程代理、虚拟代理、安全代理
5. 行为型模式
这类模式负责对象间的高效沟通和职责委派。
5.1 解释器(Interpreter)
虚拟机的机制
- 要点:给定一个语言,定义它的文法表示,并 定义一个解释器,解释语言中的句子
- 特点:解释执行语句,定义语言文法(用于编译器、规则引擎)
5.2 模板方法(Template Method)
框架
- 要点:定义一个 算法的骨架 (模板),具体实现延迟到交给子类去做
- 特点:表示一个作用于某对象结构中的各元素的操作,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤
5.3 责任链(Chain of Responsibility)
传递职责
- 要点:避免请求发送者和接收者耦合在一起,让多个对象都有可能接收到请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止
- 特点:解耦请求发送者和接收者,使多个对象都有可能接收请求,而发送者不需要知道哪个对象会处理它
5.4 命令(Command)
日志记录,可撤销
- 要点:将一个请求封装成一个对象,可以用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作
- 特点:
5.5 迭代器(Iterator)
数据集
- 要点:提供一种方法 顺序访问一个聚合对象中各个元素,而 又无需暴露该对象的内部表示
- 特点:遍历 集合中的各个元素,隐藏内部结构
5.6 中介者(Mediator)
不直接引用
- 要点:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而 使其耦合松散,而且 可以独立地改变它们之间的交互
- 特点:解耦 对象间的复杂交互,用一个中介同一封装交互逻辑,降低耦合度
5.7 备忘录(Memento)
游戏存档
- 要点:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态
- 特点:
5.8 观察者(Observer)
联动
- 要点:定义对象间的一种多对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新
- 特点:用于 建立对象之间的通知机制
5.9 状态(State)
状态变成类
- 要点:运行对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类
- 特点:
5.10 策略(Strategy)
多方案切换
- 要点:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换
- 特点:让算法可以独立于使用它的用户而变化。封装算法,灵活替换
5.11 访问者(Visitor)
数据与操作分离
- 要点:主要 将数据结构与数据操作分离
- 特点:在不改变各元素的类的前提下定义作用于这些元素的新操作
5.12 空对象(Null Object)
- 要点:一个空对象取代 NULL 对象实例的检查,这个空对象实现了相同的接口,但对请求不做任何操作或提供默认操作
- 特点:解决在系统中使用 null 值可能导致的问题,运行系统在没有合适的对象时,使用一个 “安全” 的空对象继续运行,而不是失败
