Skip to content
← 返回设计模式列表
设计意图与对象责任

按变化点选择设计模式 ​

设计意图与对象责任 ​

前置:能区分接口契约与实现,理解函数作为参数和整数分计价;Python 3.10+ 仅用于报价模型。教学范围为函数组合与GoF意图;Python 3.10+。核对日期2026-10-17。示例未执行,本轮没有安装依赖、生成协议代码、启动服务或浏览器预览。完整文件与输入见报价策略完整程序与练习;推演结论只适用于写明的模型。

策略模式解决什么变化 ​

策略模式解决什么变化:同一报价上下文需要切换算法族,而校验与收款规则应保持一致。把折扣计算作为函数传入,调用方只关心输入输出。只有固定一种公式时,直接函数比多层工厂更容易验证;模式名称不自动产生设计价值。

替换必须遵守契约 ​

替换必须遵守契约:策略接受整数分金额并返回非负金额,不得偷偷付款。纯函数易于对照输入与输出;若一个策略修改购物车,另一个不修改,即使签名相同也可能破坏可替换性。先定义副作用边界再讨论接口。

装饰器与策略区别 ​

装饰器与策略区别在于包装与替换的意图。策略替换核心算法,装饰器在相同调用边界添加日志等行为。先缓存再鉴权会有越权风险,包装顺序是行为的一部分;不能只看类图相似就认为两者等价。

从变化点定位组合边界 ​

以报价为例,输入校验和金额单位属于稳定契约;九折与满减属于可替换算法;日志属于外围行为。三者分开后,测试可以给相同输入替换算法,并核对不变量。若策略偷偷收费,单纯比较返回值就无法发现副作用,必须把“只计算”写进契约。

查看图表代码

来源与适用边界 ​

状态、策略、工厂与观察者的边界 ​

状态与策略区别 ​

状态与策略区别是状态对象通常约束转换和合法事件,策略通常由外部选择一个计算方法。订单已支付后再支付应拒绝,不只是切换一个新策略。状态机要写出起点、终点和非法边,而不能依赖对象名称暗示流程。

工厂与构造函数 ​

工厂与构造函数都处理创建,抽象工厂强调相关产品族一起变化。只按一个字符串选择一个实现的函数不必冒称完整GoF工厂方法。若增加一个产品种类就要修改所有工厂,应把这个代价写进选型依据。

观察者生命周期 ​

观察者生命周期需要退订与异常处理。同步通知被慢回调阻塞;异步通知引入排队、顺序与背压问题。发布者不持有具体消费者类型并不等于没有内存泄漏,闭包仍可能延长对象生存期。

按责任区分四种协作 ​

同一订单流程可以同时存在四种机制:工厂选择创建哪种对象,策略计算金额,状态约束能否付款,观察者在变化发生后通知订阅者。不要让折扣策略负责修改付款状态,也不要把同步通知当作持久事件投递。图示为责任分配示意,不代表一套必须引入的类层级。

查看图表代码

来源与适用边界 ​

模式误用与选择取舍 ​

过度设计识别 ​

过度设计识别应统计真实变化点。两行稳定计算拆成五层接口会增加阅读成本;当多个独立算法实际存在且测试边界明确时,策略才有收益。不要为了匹配模式目录而预先建立还没有调用者的抽象。

适配器代理外观比较 ​

适配器代理外观比较要按意图:适配器做接口转换,代理保持接口并实施访问控制或延迟访问,外观汇总多个子系统常用流程。三者都可能包装对象,但错误传播、所有权与绕过入口必须分别检查。

模式参考与历史示例 ​

模式参考与历史示例对照作者中英文资料的意图说明。旧Go示例保留创建、结构和行为三组独有案例;本课增加替换契约与负例,不把函数式示例误说为所有GoF类结构的逐字复现。

三个包装意图的对照 ​

同样是对象包对象,判断标准仍是调用方需要什么。读旧格式是适配,控制谁能读取是代理,把保存与通知合成注册是外观。若一个包装器同时做三件事,应把每项契约明确写出,避免名字掩盖错误路径。

查看图表代码

来源与适用边界 ​

继续阅读