知识卡片

表面重复与真正重复:不该为了消除相似而过早耦合独立演化的代码

普通读书笔记卡

内容

架构师往往对重复代码有一种应激式的厌恶,但重复其实分两种。真正的重复,是同一处代码每次变更都必须同步应用到所有副本;表面性的重复,则是两段代码看起来相似,但走的是不同的演进路径——它们有不同的变更速率和变更缘由,只是当下恰好长得差不多,几年后回头看很可能已经大相径庭。这种误判在[[按层水平解耦与按用例垂直切分的矩阵式解耦模式]]里尤其常见:假设某系统里两个用例的屏幕展示看起来非常相似,架构师很容易忍不住想复用同一段代码处理它们——但这里几乎肯定只是表面性重复,随着时间推移,这两个用例的屏幕展示大概率会各自演化、最终分道扬镳,若图省事让它们共享同一段代码,未来想把它们拆开时就会面临巨大挑战。这个陷阱在按用例做垂直切分时反复出现——不同用例可能因为展现形式类似、语法相似、数据库查询/表结构相似而被架构师主动耦合在一起,务必要警惕这种”看到重复就想立即消除”的条件反射,只对真正意义上的重复动手。同样的坑也出现在水平分层之间:如果某个数据库记录结构和某个屏幕展示的数据接口长得很像,很容易为了省事直接把数据库记录传给UI层、跳过额外建一个视图模型——但这里几乎肯定也只是表面性重复,多建一个视图模型的成本很低,却能维持系统水平分层之间的隔离,值得为此多写几行代码。

参考来源

- 位置:《架构整洁之道》第16章《独立性》"重复"(源文件:_epub-src/text/part0014_split_001.html) - 结论依据:原文区分真正重复(每次变更需同步应用到所有副本)与表面性重复(看似相似但演化路径不同),用两个用例屏幕展示相似、数据库记录结构与视图接口相似两个具体例子说明过早复用会给未来的拆分带来困难,直接支撑本卡片结论。 - 原始内容:其中有些是真正的重复……重复的情况中也有一些是假的,或者说这种重复只是表面性的……这里很可能只是表面性的重复……我们也一定要小心,这里几乎肯定只是一种表面性的重复。