《大话设计模式》读书笔记

0 阅读7分钟

《设计模式》读书笔记

1. 总结

设计模式本质上是“可复用、可维护、可扩展、低耦合”代码的经验总结。

学习设计模式前,先明确“面向过程”和“面向对象”的差别:

  • 面向过程:以函数为核心,关注“怎么做”(步骤)。
  • 面向对象:以对象为核心,关注“谁来做”(职责)。

面向对象三大特性:

  • 封装:把数据和行为放在一起。
  • 继承:子类继承父类能力并可扩展。
  • 多态:同一接口,不同实现。

2. 七大设计原则

2.1 开闭原则

对扩展开放,对修改关闭。尽量通过“新增”来支持新需求,而不是修改稳定代码。

2.2 里氏替换原则

子类必须可以替换父类,且不破坏原有行为约定。

2.3 依赖倒置原则

高层模块依赖抽象,不依赖具体实现。

2.4 接口隔离原则

接口要小而专一,避免“胖接口”。

2.5 单一职责原则

一个类只负责一类职责(只应有一个引起它变化的原因)。

2.6 迪米特法则(最少知道原则)

对象之间尽量少直接交互,降低耦合。

2.7 合成/聚合复用原则

优先用组合(has-a)复用,而不是继承(is-a)。


3. 设计模式分类总览

3.1 创建型(关注“怎么创建对象”)

  • 单例模式
  • 工厂方法模式
  • 抽象工厂模式
  • 建造者模式
  • 原型模式

3.2 结构型(关注“怎么组合对象/类”)

  • 适配器模式
  • 桥接模式
  • 组合模式
  • 装饰模式
  • 外观模式
  • 享元模式
  • 代理模式

3.3 行为型(关注“对象如何协作”)

  • 职责链模式
  • 命令模式
  • 解释器模式
  • 迭代器模式
  • 中介者模式
  • 备忘录模式
  • 观察者模式
  • 状态模式
  • 策略模式
  • 模板方法模式
  • 访问者模式

4. 模式笔记(按原笔记顺序整理)

4.1 简单工厂模式

定义:定义一个工厂类,根据参数创建不同具体对象。
示例:计算器支持 + - * /
优点

  • 创建逻辑集中,便于管理。
  • 客户端不用关心具体创建细节。 缺点
  • 新增功能要改工厂判断逻辑,违背开闭原则。
  • 工厂职责容易过重。

4.2 策略模式

定义:将一组算法分别封装并可互换,算法变化不影响使用方。
示例:超市活动(满减、打折、积分)。
优点

  • 新增策略通常只需加类,不改旧逻辑。
  • 策略可复用、可独立测试。 缺点
  • 策略多时类数量增加。
  • 客户端需要理解并选择策略。

4.3 装饰模式

定义:不改原对象,动态叠加新功能。
示例:换装系统(衣服、裤子、帽子、鞋子自由组合)。
优点

  • 动态扩展,灵活组合。
  • 符合开闭原则。 缺点
  • 装饰层级过多时理解成本上升。

4.4 代理模式

定义:为真实对象提供代理,控制访问并可附加增强逻辑。
示例:代送礼物。
优点

  • 职责分离(代理做控制,真实对象做业务)。
  • 可加权限、日志、缓存等横切能力。 缺点
  • 增加系统复杂度。

4.5 模板方法模式

定义:定义算法骨架,具体步骤延迟到子类实现。
示例:简历模板(固定字段 + 可变工作经历)。
优点

  • 公共逻辑上提,减少重复代码。
  • 扩展新变体方便。 缺点
  • 子类较多时维护成本上升。

4.6 外观模式

定义:给复杂子系统提供统一、简单入口。
示例:基金申购(用户只关心买入/卖出,不关心底层选股)。
优点

  • 降低使用门槛。
  • 客户端与子系统解耦。 缺点
  • 外观类可能膨胀。
  • 子系统变动可能影响外观层。

4.7 建造者模式

定义:将复杂对象的构建过程与表示分离。
示例:汉堡制作流程固定,不同品牌可复用流程。
优点

  • 构建过程可控,步骤清晰。
  • 同流程可产出不同结果。 缺点
  • 引入建造者/指挥者,结构更复杂。

4.8 观察者模式

定义:一对多依赖,主题状态变化后自动通知观察者。
示例:老板回公司,员工停止摸鱼。
优点

  • 新增观察者不改主题。
  • 发布订阅解耦。 缺点
  • 观察者过多时通知成本高。
  • 时序处理不当会出现状态一致性问题。

4.9 工厂方法模式

定义:定义创建接口,由子类决定实例化哪种产品。
优点

  • 符合开闭原则。
  • 解耦创建与使用。 缺点
  • 类数量增加。

4.10 抽象工厂模式

定义:创建“同一产品族”的一组相关对象。
示例:Windows/Mac 风格 UI(按钮 + 复选框)成套输出。
优点

  • 产品族一致性好,不易风格冲突。
  • 符合开闭原则。 缺点
  • 结构比工厂方法更复杂。

4.11 状态模式

定义:对象内部状态变化时,行为随之变化。
示例:上班状态(上午/下午/加班)行为不同。
优点

  • 消除大量 if/else。
  • 状态职责清晰,便于维护。 缺点
  • 状态类增多。

4.12 适配器模式

定义:把不兼容接口转换成目标接口。
示例:球场翻译,让中国球员和美国教练协作。
优点

  • 兼容旧系统,减少改造成本。
  • 提升复用性。 缺点
  • 增加一层间接调用和复杂度。

4.13 备忘录模式

定义:在不破坏封装的前提下保存并恢复对象状态。
示例:游戏存档/读档。
优点

  • 支持撤销与恢复。
  • 封装性好。 缺点
  • 状态多时内存开销大。

4.14 组合模式

定义:把对象组织成树形结构,表达“部分-整体”。
示例:文件夹与文件。
优点

  • 客户端可统一处理单个对象与组合对象。
  • 扩展节点方便。 缺点
  • 设计不当会让职责边界模糊。

4.15 迭代器模式

定义:顺序访问聚合对象元素,不暴露内部结构。
示例:售票员遍历车上乘客。
优点

  • 遍历逻辑与集合结构分离。
  • 符合开闭原则。 缺点
  • 简单场景可能显得偏重。

4.16 单例模式

定义:保证一个类仅有一个实例,并提供全局访问点。
示例:数据库连接池管理器。
优点

  • 避免重复创建。
  • 统一共享状态。 缺点
  • 可能引入全局状态问题。
  • 测试和扩展不够灵活。

4.17 桥接模式

定义:分离抽象与实现,让两个维度独立变化。
示例:形状(圆/方)与颜色(红/蓝)解耦组合。
优点

  • 组合爆炸问题明显缓解。
  • 扩展维度互不影响。 缺点
  • 需要提前识别变化维度。

4.18 命令模式

定义:把请求封装为对象,支持排队、记录、撤销。
示例:遥控器按钮控制开灯/关灯。
优点

  • 请求发送者与执行者解耦。
  • 易于扩展和记录操作。 缺点
  • 命令类数量增加。

4.19 职责链模式

定义:多个处理者串成链,请求沿链传递直至被处理。
示例:加薪审批链(组长→主管→...)。
优点

  • 请求方与处理方解耦。
  • 链路可灵活调整。 缺点
  • 链过长影响排查与性能。

4.20 中介者模式

定义:用中介对象封装对象间交互,避免对象互相直接引用。
示例:微信群中消息由群统一转发。
优点

  • 减少对象间网状依赖。
  • 交互逻辑集中管理。 缺点
  • 中介者容易膨胀成“上帝对象”。

4.21 享元模式

定义:共享大量细粒度对象以节省内存。
示例:文档里大量重复字符共享内在状态。
优点

  • 显著降低内存消耗。
  • 提升对象创建性能。 缺点
  • 内外状态拆分增加理解成本。

4.22 解释器模式

定义:定义语法规则并提供解释执行机制。
示例:解析并计算表达式 1 + 2 + 3
优点

  • 语法扩展相对直接。
  • 规则结构清晰。 缺点
  • 复杂语法会导致类爆炸。

4.23 访问者模式

定义:在不改变元素类的前提下,为元素结构新增操作。
示例:对 CPU/硬盘/主板新增“价格计算”“序列化输出”。
优点

  • 新增“操作”方便,符合开闭原则。
  • 相关操作集中。 缺点
  • 新增“元素类型”困难。
  • 可能破坏部分封装。

5. 学习建议

  • 先掌握原则,再记模式,避免“为模式而模式”。
  • 每学一个模式,至少回答三个问题:
    • 解决了什么痛点?
    • 代价是什么?
    • 什么时候不该用?
  • 先在小场景用(日志、优惠、审批、通知),再用于业务核心。