Skip to content

约 4 分钟阅读

设计模式 ​

设计模式描述反复出现的对象设计问题:对象怎样创建、怎样组合、怎样协作。它提供一套交流设计的语言,是否采用仍要看变化成本。稳定的两个分支可以直接保留;只有当新增需求反复牵动旧代码时,抽象才有明确收益。

设计模式的三类问题与常见模式

从订单导出认识三类问题 ​

用户点击“导出订单”后,系统需要创建导出任务、接入文件存储、选择 CSV 或 Excel 渲染方式。这三个变化点对应不同模式,不需要把整个流程套成一种模式。

变化点直接写法遇到的问题可考虑的结构
任务有筛选条件、列配置、时区等可选项构造函数参数难以辨认,非法组合难检查建造者集中构建与校验
对象存储 SDK 的上传接口不同每个业务调用方都重复转换参数和错误码适配器提供内部上传端口
CSV 与 Excel 的渲染算法不同新格式不断修改导出主流程策略隔离渲染算法,由请求或配置选择

重构是否有效,要再加一种格式来验证:新增渲染策略并注册,旧格式的输出、错误处理和资源释放仍然通过测试。策略只隔离算法,并不会自动解决大文件内存占用、任务重试或下载权限;这些属于项目实践与架构边界。

按问题选择 ​

从变化位置选择模式的判断路径

图中的模式是候选。先确认调用方希望保持什么稳定,再选择隔离方式。例如“包装一个对象”既可能是装饰器,也可能是代理,区别取决于增加职责还是控制访问。

容易混淆的模式判断依据订单系统中的例子
策略 / 状态算法选择,还是对象生命周期约束选择优惠算法 / 已发货订单不能再取消
策略 / 模板方法委托可替换算法,还是继承固定流程骨架替换文件渲染器 / 固定导出步骤并覆盖部分步骤
适配器 / 外观转换不兼容接口,还是简化子系统入口转换存储 SDK / 封装创建导出任务的协调入口
装饰器 / 代理叠加职责,还是管理目标访问日志输出加前缀 / 调用前校验下载权限
工厂方法 / 抽象工厂 / 建造者一个产品的创建、一组相关产品,还是复杂对象的组装创建渲染器 / 成套创建同风格控件 / 组装导出参数

分类与详细页 ​

创建型模式把产品选择、初始化或组装从使用方分离;不意味着每个 new 都需要工厂。单例的唯一性也有范围,例如 Java 通常以类加载器为边界,不能保证多个进程共享同一实例。

创建型主要变化
单例约定范围内的实例数量与访问入口
工厂方法由具体创建者决定产品实现
抽象工厂一组相关产品的一致创建
建造者复杂对象的构建步骤与表示
原型从已有对象复制,明确共享和独立字段

结构型模式组织对象之间的关系。包装层应有清楚目的;每加一层都需要解释它如何转发调用、处理异常和管理资源。

结构型主要变化
适配器 / 桥接接口兼容 / 两个独立变化维度
组合树结构中整体与叶子的统一使用
装饰器 / 代理职责叠加 / 访问控制
外观 / 享元简化入口 / 共享可复用状态

行为型模式分配协作职责。进程内观察者与消息队列有不同的交付边界;命令封装也不天然具备撤销能力,必须另外定义逆操作或保存恢复信息。

行为型主要变化
策略 / 模板方法算法 / 流程中的步骤
状态生命周期约束与允许动作
观察者 / 中介者变化通知 / 多方协调
责任链 / 命令处理顺序 / 请求对象化
迭代器 / 访问者遍历 / 在稳定结构上增加操作
备忘录 / 解释器状态恢复 / 简单语言解释

阅读与验收 ​

先读设计原则建立判断依据,再从当前代码中选择一个真实变化点,阅读对应模式。工厂、适配器、策略通常比较容易与业务对应,桥接、访问者、解释器适合在遇到相应结构后再深入。

一次重构至少验证三件事:旧行为不变;新增同类需求的修改范围更集中;异常、并发和资源生命周期没有因新增抽象被隐藏。若只是类变多、调用链变长,却没有减少变更影响,直接设计往往更合适。

别急,先让缓存热一下。