按变化点选择设计模式
设计意图与对象责任
前置:能区分接口契约与实现,理解函数作为参数和整数分计价;Python 3.10+ 仅用于报价模型。教学范围为函数组合与GoF意图;Python 3.10+。核对日期2026-10-17。示例未执行,本轮没有安装依赖、生成协议代码、启动服务或浏览器预览。完整文件与输入见报价策略完整程序与练习;推演结论只适用于写明的模型。
策略模式解决什么变化
策略模式解决什么变化:同一报价上下文需要切换算法族,而校验与收款规则应保持一致。把折扣计算作为函数传入,调用方只关心输入输出。只有固定一种公式时,直接函数比多层工厂更容易验证;模式名称不自动产生设计价值。
替换必须遵守契约
替换必须遵守契约:策略接受整数分金额并返回非负金额,不得偷偷付款。纯函数易于对照输入与输出;若一个策略修改购物车,另一个不修改,即使签名相同也可能破坏可替换性。先定义副作用边界再讨论接口。
装饰器与策略区别
装饰器与策略区别在于包装与替换的意图。策略替换核心算法,装饰器在相同调用边界添加日志等行为。先缓存再鉴权会有越权风险,包装顺序是行为的一部分;不能只看类图相似就认为两者等价。
从变化点定位组合边界
以报价为例,输入校验和金额单位属于稳定契约;九折与满减属于可替换算法;日志属于外围行为。三者分开后,测试可以给相同输入替换算法,并核对不变量。若策略偷偷收费,单纯比较返回值就无法发现副作用,必须把“只计算”写进契约。
查看图表代码
来源与适用边界
- 英文官方、作者或规范原文:本专题机制依据;按上述固定版本族阅读。
- 中文官方或作者资料:用于术语和讲解交叉核对,冲突以原始规范为准。
状态、策略、工厂与观察者的边界
状态与策略区别
状态与策略区别是状态对象通常约束转换和合法事件,策略通常由外部选择一个计算方法。订单已支付后再支付应拒绝,不只是切换一个新策略。状态机要写出起点、终点和非法边,而不能依赖对象名称暗示流程。
工厂与构造函数
工厂与构造函数都处理创建,抽象工厂强调相关产品族一起变化。只按一个字符串选择一个实现的函数不必冒称完整GoF工厂方法。若增加一个产品种类就要修改所有工厂,应把这个代价写进选型依据。
观察者生命周期
观察者生命周期需要退订与异常处理。同步通知被慢回调阻塞;异步通知引入排队、顺序与背压问题。发布者不持有具体消费者类型并不等于没有内存泄漏,闭包仍可能延长对象生存期。
按责任区分四种协作
同一订单流程可以同时存在四种机制:工厂选择创建哪种对象,策略计算金额,状态约束能否付款,观察者在变化发生后通知订阅者。不要让折扣策略负责修改付款状态,也不要把同步通知当作持久事件投递。图示为责任分配示意,不代表一套必须引入的类层级。
查看图表代码
来源与适用边界
- 英文官方、作者或规范原文:本专题机制依据;按上述固定版本族阅读。
- 中文官方或作者资料:用于术语和讲解交叉核对,冲突以原始规范为准。
模式误用与选择取舍
过度设计识别
过度设计识别应统计真实变化点。两行稳定计算拆成五层接口会增加阅读成本;当多个独立算法实际存在且测试边界明确时,策略才有收益。不要为了匹配模式目录而预先建立还没有调用者的抽象。
适配器代理外观比较
适配器代理外观比较要按意图:适配器做接口转换,代理保持接口并实施访问控制或延迟访问,外观汇总多个子系统常用流程。三者都可能包装对象,但错误传播、所有权与绕过入口必须分别检查。
模式参考与历史示例
模式参考与历史示例对照作者中英文资料的意图说明。旧Go示例保留创建、结构和行为三组独有案例;本课增加替换契约与负例,不把函数式示例误说为所有GoF类结构的逐字复现。
三个包装意图的对照
同样是对象包对象,判断标准仍是调用方需要什么。读旧格式是适配,控制谁能读取是代理,把保存与通知合成注册是外观。若一个包装器同时做三件事,应把每项契约明确写出,避免名字掩盖错误路径。
查看图表代码
来源与适用边界
- 英文官方、作者或规范原文:本专题机制依据;按上述固定版本族阅读。
- 中文官方或作者资料:用于术语和讲解交叉核对,冲突以原始规范为准。
- 相关既有参考:原URL与专业范围保留;历史案例不能自动代表当前实现。
继续阅读
- 策略组合实践
- 设计意图与对象责任
- 设计意图与对象责任