代码的简单设计五原则(大师程序员Kent Beck)
代码设计的标准在哪里? 简单性:我们重视刚刚够用的设计。只为当下设计,不为未来可能出现的需求做设计。但是,我们做出的决策应当允许软件快速变更,能够快速响应需求变化。 设计的好坏本身没有一个标准的答案,什么是好的设计?便成了公说公有理,婆说婆有理的问题,谁也难以说服谁。 抽象的设计问题大大提升了初学者的学习门槛,想得太多怕被说过度设计,吃饱撑着没事找事。想少了,又怕被人认为能力不足,无脑编码。到底怎么办,怎么样才能做出好的设计? 极限编程领域的大师程序员Kent Beck很早前就提出了4条相对容易理解的参考原则: 原则一:通过测试(信仰) 「通过测试」 通常会被一概地理解为通过自己在项目中的各种测试(自动化 + 手工),这么理解,也没有什么问题,但是需要满足两个前提条件: 测试覆盖率达到100% 所有测试都是有效的 如果你的项目中没法满足这两点,当然,99%的项目是做不到的(还有1%存在传说中)。此时你需要换一个角度去理解 通过测试。 你为什么写测试?测试在测什么?不就是为了增强你对系统功能是否满足了业务需求的信心吗?所以「通过测试 」广义理解为要满足业务需求,不论是自动化测试还是手工测试,你需要做的是满足业务需求,只不过我们提倡尽可能编写足够的自动化回归测试。 原则二:消除重复(职责) “重复乃万恶之源——Kent Beck 没有说过” 重复意味着低内聚、高耦合,导致的后果是难以修改(霰弹式修改),必然降低系统对变化的响应力。响应力的降低势必会造成维护工作量的提升,我的简单设计价值观 一文中的 懒惰 将驱使我尽我所能消除这些重复,从而减少修改时的工作量,提升软件的响应力。 原则三:揭示意图(初衷) 揭示意图,听起来是一个不可言说的概念,怎样表示揭示意图了呢?对于这一条,我们很难有一个标准且完美的答案,做不到完美,但不妨碍我们努力尝试趋近完美。 你可以在编码过程中,不断问自己:代码容易理解吗?它有没有偏离它的初衷(业务需求)?紧接着,进一步探索这背后暴露的行为信号 -- 「解释」: 新人了解了业务需求后,能够第一时间清晰地从代码中找到对应的代码吗? 你需要额外对一个新人解释代码的含义吗?如果要,你要解释到什么程度? 这几个问题会让你不断反思你的代码能够体现业务初衷吗?变量、方法以及类的命名等,你时刻都保持警惕的是:赋予它一个更加准确表达业务的名字,一个不要额外解释的名字。从而让读者能够在深入细节之前就能够在较高层次上快速理解代码的意图。 原则四:最少元素(精髓) 既然说的是代码,那么充斥在你的代码库中的任何东西都可以理解是元素。当然,我们还是焦点聚焦在与代码相关的元素,比如,变量、常量、注释、注解、关键字、包。 「最少元素」 的核心思想是:在不必要的时候,尽可能减少代码元素来降低代码复杂度,保持简洁,贯彻less is more的思想,它道出了简单设计的精髓。 原则五:前四条优先级依次降低(灵魂) 简单设计前四条原则给设计决策提供了指导,在实际运用过程中,当面临冲突时,我们如何取舍,Kent Beck也提出一个优先级:通过测试 > 消除重复 >= 揭示意图 > 最少元素。 以上四条优先级依次降低,这就话有点类似敏捷宣言中的最后一句:也就是说,尽管右项有其价值,我们更重视左项的价值。 通过测试 消除重复 揭示意图 最少元素 以上四条优先级依次降低 简单设计五原则中,测试要确保通过(满足需求)、重复应该被消除、元素没必要就不要存在,这几条看起来相对具体,而且能见字如意。但揭示意图这样一个每个人持有不一样标准的概念,它代表了代码的可理解性,可理解性的参考则要回到业务源头,是否准确表达了业务概念。最后,优先级原则是万万不可忽略的,否则这个框架就失去了灵魂和生命力。 代码是否易读懂,除了自我审视,还需要多几个大脑,比如:Code Review、结对编程。