章节摘要:折扣规则越加越多,灯塔小组发现一个怪事:写测试顺手的时候,接口也变好用了;反过来接口一乱,测试先写不下去。本章沿这条线把"测试先行浮现设计"从感觉变成机制——测试作为第一个使用者逼出好接口,设计模式在循环里怎么演练,SOLID 原则各落在循环的哪个位置。读完你应能解释并用好"TDD 是设计技术"这半句常被忽略的话。
周五评审会上,产品宣布下季度接入三平台优惠券。小林心里一沉:现在的 rate 里折扣逻辑写死在函数体里,加个平台要开膛一次。老周翻开测试文件说:加吧,测试会替我们指路的。接下来的三轮循环里,测试先要求"平台券与店铺券叠加上限",再要求"黑名单平台不参与",每条红灯都逼着折扣逻辑往外挪一点——挪到最后,策略结构自己出现了:折扣计算器只依赖"可计算"协议,各平台各领各的策略。设计没有事先画出来,是被测试一格一格挤出来的。
本章的转折点是视角切换:把测试从"验证者"改成"第一个客户"。客户不关心你怎么实现,只关心好不好用——接口的形状于是由使用便利性决定,而非实现便利性。第二转折在"模式的出现时机":预先套模式常见过度设计,因为模式是针对变化的预案,而变化只有来了才知道长什么样;测试先行把变化的出现时刻转化为红灯时刻,模式恰好在需求落地那一刻登场,不多不少。结论:TDD 的全称里该有个逗号——测试驱动开发,驱动的是设计,测试只是传动装置。这也是它区别于"测试活动"的根本身份:与其说它在验证一个已有设计,不如说它在持续追问设计能不能再简单一点、接口能不能再好用一点,追问的频率高到设计来不及腐化。
本章的演练依赖第 3 章的替身功夫(策略与观察者的红灯都要替身参与)与第 2 章的重构手感。三个演练的代码都在折扣、报表、库存三个真实需求上展开,难度递增,建议顺序读:先看懂"模式如何被逼出来",再回头在编辑器里把三段代码补全。读法上有个提醒:本章处处与设计模式的教科书冲突——那不是 bug 是立场,冲突点全部标了"事后命名",带着这个关键词读,张力会变成清晰。
设计讲的是"从零长出好结构";现实常常相反——接手的是没有测试的旧代码。第 5 章把镜头转向金字塔分层、遗留代码改造与时间异步这些硬骨头,骨架功夫(替身、夹具)将在那里兑现价值。