23种设计模式
目录
设计模式
命迭备 观策中 责访状(则防撞)
类设计模式和对象设计模式的特征和区别(DeepSeek)_类设计是什么-CSDN博客
以下为看文章后的个人理解
分类的意义
- 问题导向:开发者可根据需求快速定位模式类型。
- 需要灵活创建对象?→ 创建型。
- 需要整合现有组件?→ 结构型。
- 需要优化对象协作?→ 行为型。
- 设计原则体现:
- 创建型体现解耦(单一职责、依赖倒置)。
- 结构型体现组合优于继承。
- 行为型体现松耦合和开闭原则。
- 学习路径清晰:分类降低了理解复杂度,便于逐步掌握。
类比说明
- 创建型 ≈ “如何造零件”(工厂生产螺丝还是定制齿轮)。
- 结构型 ≈ “如何组装零件”(用螺丝还是胶水连接)。
- 行为型 ≈ “零件如何协作”(齿轮转动如何带动其他部件)。
这种分类并非绝对(某些模式可能跨类别),但提供了清晰的思维框架,是设计模式领域的通用语言。
创建型
- 工厂方法:子类决定创建哪个对象。
- 抽象工厂:创建相关对象族。
- 单例:确保全局唯一实例。
- 建造者:分步构建复杂对象。
- 原型:通过克隆生成对象。
结构型
适配器模式 ①将一个对象加以包装以给客户提供其希望的另外一个接口
装饰器模式 ②将一个对象加以包装以提供一些额外的行为
代理模式 ③将一个对象加以包装以控制对这个对象的访问
外观模式 ④将一系列对象加以包装以简化其接口
适配器模式:
- 目的:将一个类的接口转换为另一个接口,使得原本不兼容的类可以协同工作。
- 实现:
- 原对象A,方法(接口)X
- 原对象A新加一个属性对象B(有接口Y),调用原接口X时,可以走原逻辑,也可以去调用层类B实现的另一个接口Y。这样就从 X -> Y
桥接模式:
- 目的:用于将抽象部分与实现部分分离,使得它们可以独立地变化。
- 实现:
- 原对象A
- 原对象A新加一个属性 接口B(有X方法),新建A对象时,会给接口B赋值不同的实现类,调用B的X方法时就会有不同的实现。
组合模式:
- 目的:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。是用于把一组相似的对象当作一个单一的对象。这种模式创建了一个包含自己对象组的类。
- 实现:原对象A,其有一个字段是对象A集合
装饰器模式:
- 目的:动态地给一个对象添加额外的职责,同时不改变其结构。装饰器模式提供了一种灵活的替代继承方式来扩展功能。
- 实现:
- 原对象A,方法(接口)X
- 新加一个对象B,其有一个属性是原对象A,对象B有方法Y的第一行代码就是调用A的方法X,然后后面追加新功能的代码实现,添加额外的职责
外观模式:
- 目的:为一个复杂的子系统提供一个一致的高层接口。这样,客户端代码就可以通过这个简化的接口与子系统交互,而不需要了解子系统内部的复杂性。
- 实现:
- 原对象A B C
- 新加一个对象D,其有属性是原对象A B C。通关调用D中的方法调用A B C中的方法。
享元模式:
-
目的:通过共享对象来减少创建大量相似对象时的内存消耗。
-
实现:
-
创建的对象放在集合里,下次来可以直接取,不需要再创建。
-
类似线程池,复用线程。
-
代理模式:
- 目的:为其他对象提供一种代理以控制对这个对象的访问。代理模式解决的是在直接访问某些对象时可能遇到的问题,例如对象创建成本高、需要安全控制或远程访问等
- 与适配器模式的区别:适配器模式改变接口,而代理模式不改变接口。
- 与装饰器模式的区别:装饰器模式用于增强功能,代理模式用于控制访问。
- 实现:
- 原对象A,方法(接口)X
- 新加一个对象B,也有方法(接口)X,其有一个属性是原对象A,对象B调用方法X是,属性对象A为空时会去创建A并赋值,不为空时就去直接调用A的方法(接口)X。
行为型
模板方法模式:
- 目的:在父类中定义了算法的骨架,并允许子类在不改变算法结构的前提下重定义算法的某些特定步骤。
- 实现:
- 模板方法:在抽象父类中定义,抽象方法和具体方法(模板方法)。
- 抽象方法:抽象方法由子类实现,代表算法的可变部分。
- 具体方法:在抽象父类中实现,通常,代表算法的不变部分。为了防止恶意修改,模板方法通常使用
final关键字修饰,避免被子类重写。
解释器模式:
-
目的:定义一种语言的文法表示,并创建一个解释器,该解释器能够解释该语言中的句子。
-
应用:
- 编译器:解释器模式可以用于编译器设计,将源代码解释为目标代码。
观察者模式:
- 目的:创建了对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖于它的对象都会得到通知并自动更新。
- 实现:
- 观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法X。
- 主题(Subject):也称为被观察者,具有一个观察者list。new观察者时,会把观察者放入主题的观察者list中。主题(Subject)状态改变时,通过遍历观察者list,调用观察者实现的更新方法X,通知所有观察者。
策略模式:
- 目的:将每个算法封装起来,使它们可以互换使用。
- 实现:和桥接模式差不多。原对象A新加一个属性 接口B(有X方法),新建A对象时,会给接口B赋值不同的实现类,调用B的X方法时就会有不同的实现。
命令模式:
- 目的:将请求封装为一个对象,允许用户使用不同的请求对客户端进行参数化。
- 实现:
- 定义命令接口:所有命令必须实现的接口。
- 创建具体命令:实现命令接口的具体类,包含执行请求的方法。
- 调用者:持有命令对象并触发命令的执行。
- 接收者:实际执行命令的对象。
相似模式的理解
策略模式和桥接模式例子:(访问者模式也与策略模式相似)
同一段代码从不同角度解读,既可以表示策略模式也可以表示桥接模式,尤其是在简单的示例中。这是因为两者的核心结构(接口 + 实现类 + 组合关系)高度相似。但能否真正“同时表示”两种模式,取决于代码的设计意图和实际应用场景。
1. 为什么同一段代码可能被混淆?
示例代码:
// 公共接口(Strategy/Implementor)
interface Operation {
void execute();
}
// 具体实现(ConcreteStrategy/ConcreteImplementor)
class Add implements Operation {
public void execute() { System.out.println("加法"); }
}
class Multiply implements Operation {
public void execute() { System.out.println("乘法"); }
}
// 上下文/抽象类(Context/Abstraction)
class Calculator {
private Operation operation;
public void setOperation(Operation op) { this.operation = op; }
public void calculate() { operation.execute(); }
}
如何解读?
- 策略模式视角:
Operation是算法接口,Add和Multiply是具体算法。Calculator是上下文,动态切换算法(加法或乘法)。
- 桥接模式视角:
Operation是实现部分接口,Add和Multiply是具体实现。Calculator是抽象部分,通过组合调用实现部分的操作。
2. 关键区别:设计意图决定模式归属
虽然代码结构相同,但模式的实际归属取决于开发者想解决什么问题:
| 维度 | 策略模式 | 桥接模式 |
|---|---|---|
| 问题领域 | 行为的选择(如何做) | 抽象与实现的解耦(做什么 vs 怎么做) |
| 变化方向 | 同一行为的多种实现(算法替换) | 多个维度的独立变化(如设备+遥控器) |
| 典型关系 | 一对多(一个上下文对多种策略) | 多对多(抽象和实现自由组合) |
举例说明:
- 如果
Calculator的目标是动态切换计算逻辑(比如根据用户输入选择加法或乘法),则是策略模式。 - 如果
Calculator的目标是分离计算器的抽象操作(如按钮)和具体计算实现(比如支持不同品牌的硬件计算模块),则是桥接模式。
3. 何时需要明确区分?
当代码复杂度增加时,两种模式会走向不同的演化方向:
策略模式的扩展
- 新增算法(如
Subtract),但Calculator的接口不变。 - 强调算法的可替换性。
桥接模式的扩展
- 抽象部分(如
Calculator)可能派生出子类(如ScientificCalculator)。 - 实现部分(如
Operation)可能扩展为多层级(如HardwareAdd、SoftwareAdd)。 - 强调抽象和实现的双向独立演化。
4. 总结
- 可以共用代码:简单场景下,一段代码可能同时满足两种模式的结构。
- 本质不同:模式的命名取决于设计意图,而非单纯代码结构。
- 如何选择:
- 如果需要灵活切换行为 → 策略模式。
- 如果需要分离抽象层次和实现层次 → 桥接模式。
最终,模式是思想的体现,不是代码的枷锁。理解意图比套用模式更重要。
设计模式的核心思想总结
- 多用组合,少用继承(几乎所有模式都体现这点)
- 针对接口编程,而不是实现(组合的都是接口)
- 找出变化的部分,将其封装(变化的部分就是被组合的对象)
- 松耦合,高内聚(组合让对象之间依赖接口而非具体类)
所有的设计模式都在不同场景下展示了如何通过合理的组合设计来解决问题,而不是通过复杂的继承层次。
浙公网安备 33010602011771号