代码出现结构味道时的处理动作

从识别结构问题到决定是否引入模式的完整动作序列——不是教你背模式,是教你判断要不要用

本页目录

画出当前的对象关系图

不要在脑子里分析。拿张纸或用工具画出涉及的核心类和它们之间的关系:谁持有谁的引用?谁调用谁的方法?继承关系是什么?

标注每个类当前承担的职责。一个类如果需要写三个以上不同方向的职责说明,它大概率承担太多了。

完成标准:图上的箭头能和实际代码对应上。如果画不出来,先读代码再画。

标注最近三次变更的改动范围

在图上用不同颜色标出最近三次需求变更分别改了哪些类。

如果三次变更改的都是同一组类,说明这些类之间的耦合度高——它们总是要一起改。如果三次变更每次都要改很多类,说明变更的影响范围没有被结构约束住。

这一步的目的不是找"坏代码",是找"变更方向"。代码的变更方向比代码当前的样子更重要。

判断未来最可能的变更方向

根据产品路线图、技术债务清单或自己的经验判断:这段代码未来半年最可能沿哪个方向变化?

  • 行为变体会增加(加新的策略、处理方式、规则)→ Strategy / State
  • 功能需要动态叠加(日志加脱敏加压缩加路由)→ Decorator
  • 对象创建方式会变(不同环境不同配置不同产品)→ Factory / Builder
  • 多个模块的交互会变复杂(新增模块、新增交互路径)→ Mediator / Observer
  • 流程骨架固定但步骤实现可换 → Template Method

判断不需要精确。能说出"大概会往这个方向变"就够了。如果完全说不出来,暂时不引入模式是最安全的选择。

评估引入成本和收益

确定了候选模式之后,做一个快速评估:

引入需要改多少现有代码?新增多少类或接口?团队里几个人能理解这个结构?引入后下一次同方向变更的改动量能降多少?

如果引入成本大于未来三次同方向变更的累计成本,暂时不值得。先用简单方案顶住,等变更真的发生了再重构。

一个实用的判断基准:如果引入模式后新增的类数量超过现有变体数量的两倍,大概率是过度设计。

做最小的结构改造

决定引入之后,不要一步到位把整个系统重构。先在最痛的那个点做最小的模式引入。

比如决定用 Strategy:先抽出一个接口,把现有的 if-else 中最大的两个分支变成两个实现类。其他分支暂时保留在原来的代码里。跑通测试确认没有回归之后,再逐步迁移剩余分支。

完成标准:改完之后画一张新的对象关系图,和改之前的对比。变更影响范围应该明显缩小了。如果没有——回退,重新评估候选模式是否选对了。

同分类继续看