以下是 23种设计模式的生活化场景 及其核心对比,通过日常例子和比喻帮助理解它们的本质区别和应用场景:
创建型模式(5种)
1. 工厂方法(Factory Method)
• 场景 :快餐店的点餐系统。
• 问题 :顾客需要不同套餐(汉堡+可乐、炸鸡+薯条),但不想关心具体制作过程。
• 解决 :定义一个「创建餐品」的接口,由子类(不同分店)决定具体实现。
• 对比:与简单工厂不同,工厂方法将创建逻辑延迟到子类。
2. 抽象工厂(Abstract Factory)
• 场景 :家具店提供不同风格(北欧、中式)的成套家具。
• 问题 :确保沙发、桌子、椅子风格统一。
• 解决 :抽象工厂接口定义「创建沙发」「创建桌子」等方法,具体工厂(北欧工厂、中式工厂)实现全套产品。
• 对比:工厂方法创建单一产品,抽象工厂创建产品族。
3. 建造者(Builder)
• 场景 :组装一台高配电脑。
• 问题 :CPU、内存、硬盘等组件组合复杂,需要逐步配置。
• 解决 :建造者类定义组装步骤(setCPU()
、setRAM()
),指挥者(Director)按顺序调用,最终生成完整电脑。
• 对比:与工厂模式不同,建造者强调分步骤构建复杂对象。
4. 原型(Prototype)
• 场景 :复印机复制文件。
• 问题 :避免重复创建复杂对象的初始化过程(如加载大文件)。
• 解决 :对象实现clone()
方法,直接复制自身。
• 对比:原型通过克隆避免重复计算,工厂通过子类创建新对象。
5. 单例(Singleton)
• 场景 :公司的打印机服务。
• 问题 :确保整个系统只有一个打印任务队列。
• 解决 :私有化构造函数,提供全局访问点getInstance()
。
• 对比:单例强调唯一性,其他创建型模式关注对象创建方式。
结构型模式(7种)
6. 适配器(Adapter)
• 场景 :电源转接头(美标→欧标)。
• 问题 :已有接口(美标插头)无法直接使用(欧标插座)。
• 解决 :适配器类包装旧接口,转换为目标接口。
• 对比:适配器解决接口不兼容,桥接模式提前设计抽象与实现分离。
7. 桥接(Bridge)
• 场景 :遥控器控制不同品牌电视。
• 问题 :遥控器(抽象)和电视(实现)独立变化。
• 解决 :通过组合(遥控器持有电视接口)解耦两者。
• 对比:桥接是主动设计解耦,适配器是被动补救兼容。
8. 组合(Composite)
• 场景 :文件系统中的文件夹和文件。
• 问题 :统一处理单个文件和文件夹。
• 解决 :定义抽象组件(Component
),叶子节点(文件)和容器(文件夹)实现相同接口。
• 对比:组合处理树形结构,装饰者为对象动态添加功能。
9. 装饰者(Decorator)
• 场景 :给咖啡加料(牛奶、糖)。
• 问题 :动态扩展功能,避免继承爆炸。
• 解决 :装饰者类包装原有对象,递归叠加功能。
• 对比:装饰者运行时添加功能,代理模式控制访问或增强功能。
10. 外观(Facade)
• 场景 :智能家居一键模式。
• 问题 :操作多个子系统(灯光、空调、音响)太复杂。
• 解决 :外观类提供统一接口(startMovieMode()
),内部调用子系统接口。
• 对比:外观简化接口,中介者协调对象间通信。
11. 享元(Flyweight)
• 场景 :在线游戏中的重复子弹对象。
• 问题 :大量子弹实例消耗内存,但大部分属性(颜色、模型)可共享。
• 解决 :分离内部状态(共享属性)和外部状态(位置、速度),缓存重复部分。
• 对比:享元优化资源,原型优化对象创建成本。
12. 代理(Proxy)
• 场景 :明星经纪人。
• 问题 :控制对真实对象的访问(如权限检查、延迟加载)。
• 解决 :代理类持有真实对象的引用,在调用前后添加逻辑。
• 对比:代理控制访问,装饰者增强功能。
行为型模式(11种)
13. 责任链(Chain of Responsibility)
• 场景 :客服系统的多级投诉处理。
• 问题 :请求(用户投诉)需经过多个处理者(客服→主管→经理)。
• 解决 :每个处理者决定自己处理或传递给下一级。
• 对比:责任链传递请求,命令模式封装请求为对象。
14. 命令(Command)
• 场景 :餐厅点餐订单。
• 问题 :将请求(点菜)封装为对象,支持撤销、排队、日志记录。
• 解决 :定义Command
接口(execute()
、undo()
),服务员(Invoker)调用命令。
• 对比:命令解耦请求发送者和执行者,策略模式解耦算法。
15. 解释器(Interpreter)
• 场景 :计算器解析数学表达式。
• 问题 :定义一种语法(如1+2*3
)并解释执行。
• 解决 :构建语法树,定义终结符(数字)和非终结符(运算符)的解释逻辑。
• 对比:解释器处理特定语法,模板方法定义算法骨架。
16. 迭代器(Iterator)
• 场景 :书架的书籍遍历。
• 问题 :统一访问集合元素(数组、链表),隐藏底层实现。
• 解决 :定义Iterator
接口(hasNext()
、next()
),集合类提供迭代器。
• 对比:迭代器解耦遍历逻辑,访问者模式解耦数据结构和操作。
17. 中介者(Mediator)
• 场景 :机场控制塔协调航班起降。
• 问题 :多个对象(飞机)直接通信会导致依赖混乱。
• 解决 :中介者封装交互逻辑,对象只与中介者通信。
• 对比:中介者协调多对象,外观模式简化子系统调用。
18. 备忘录(Memento)
• 场景 :游戏存档。
• 问题 :捕获对象状态(角色血量、位置),支持回滚。
• 解决 :备忘录对象保存状态,原发者(游戏角色)负责生成和恢复状态。
• 对比:备忘录保存状态,命令模式封装操作。
19. 观察者(Observer)
• 场景 :微信公众号订阅。
• 问题 :用户(订阅者)需要实时接收更新(新文章)。
• 解决 :主题(公众号)维护观察者列表,状态变化时通知所有观察者。
• 对比:观察者一对多通知,中介者多对多协调。
20. 状态(State)
• 场景 :红绿灯状态切换。
• 问题 :对象(红绿灯)行为随状态(红、黄、绿)改变。
• 解决 :将状态抽象为接口,具体状态类实现不同行为。
• 对比:状态模式处理对象内部状态变化,策略模式切换算法。
21. 策略(Strategy)
• 场景 :导航App选择路线(最快、最短、避开收费)。
• 问题 :动态切换算法(路线计算逻辑)。
• 解决 :定义策略接口,不同策略类实现算法,客户端自由切换。
• 对比:策略模式解耦算法,命令模式解耦请求。
22. 模板方法(Template Method)
• 场景 :冲泡饮料的固定流程(煮水→加原料→倒杯)。
• 问题 :定义算法骨架(流程),子类实现具体步骤(咖啡、茶)。
• 解决 :抽象类定义模板方法,子类重写钩子方法。
• 对比:模板方法固定流程,策略模式灵活替换算法。
23. 访问者(Visitor)
• 场景 :医生检查不同患者(小孩、老人)。
• 问题 :在不修改患者类的前提下,添加新操作(体检、开药)。
• 解决 :访问者接口定义visitChild()
、visitElder()
,患者类接受访问者。
• 对比:访问者分离数据结构和操作,迭代器分离遍历逻辑。
🔍 模式对比总结
分类 | 模式对比 |
---|---|
创建型 | 工厂方法(单一产品) vs 抽象工厂(产品族) vs 建造者(分步构建复杂对象) |
结构型 | 适配器(接口转换) vs 桥接(抽象与实现解耦) vs 装饰者(动态扩展功能) vs 代理(控制访问) |
行为型 | 策略(算法替换) vs 状态(状态驱动行为) vs 观察者(事件通知) vs 责任链(请求传递) |
核心目标 | 创建型→对象创建方式;结构型→对象组合方式;行为型→对象间协作与职责分配 |