简单设计的四个要素(译)

96
九彩拼盘
2015.09.12 18:32* 字数 1771

原文

我意识到我从来没有将这些写下来,虽然我在作为一个教练和导师时会常常提到这些。
更新于2013年12月11日。你读完这篇文章后,一定会想读下一篇文章

我将所有从Kent Beck的研究工作中学到的,关于如何进行有效的面向对象的简单设计概括为四个要素。

我是这么定义简单设计的。简单设计指的是

  1. 通过测试
  2. 尽可能少的拷贝
  3. 尽可能的清晰
  4. 更少的元素

我是将这些要素按照优先级排序的。首先,我会通过复制和拷贝来通过测试,一旦通过测试,我会马上删除重复的部分。我会将那些重复的代码放进一个叫foo()的方法来去掉重复的代码。尽管foo()的方法的名字不会存在超过15分钟。最后,我会乐意的引入接口,类,方法和变量来让代码清晰起来。通常来说,我让代码越清晰,我越容易的找出能删减的元素。

有人将“尽可能少的拷贝”和“尽可能的清晰”放在并列第二的位置。但我不这么认为。我的经验是,删除重复对我的帮助比修改坏的命名的用处更大。通过删除重复,一个合适的结构就出现了,然而,坏的命名只是高亮了那些与其命名不合适的职责。我把这个观察结果作为我的例子的关键要素。“不需要尝试的结构”。

现在,我需要说明,做为一个测试驱动开发(现在同样也是一个行为驱动的开发者)的实践者。我写测试就如同呼吸一样。因此,我不会强调测试这个部分。

  1. 通过测试
  2. 尽可能少的拷贝
  3. 尽可能的清晰
  4. 更少的元素

我同样会说明的是,我已经知道只有很少重复内容,清晰明了,没有多余内容的代码是怎样的,因此我也不会强调更少的元素这点。

  1. 通过测试
  2. 尽可能少的拷贝
  3. 尽可能的清晰
  4. 更少的元素

正如一些人评论的那样,虽然我们可以大致上同意重复是由什么构成的,以及“清晰”仍然是激烈争论的焦点。我在开发的很多年中,清晰的代码对我产生一些启发式的主意很有帮助,并且它们往往是与命名相关的。关于这个主题,我可以写一篇很长的文章或者一本很短的书,让我们以一个例子来作为开始:一个改善命名的过程。

名字一般经历这四个阶段:没有意义的,准确的,精确的,有意义的。懒惰和没有充分的了解让我们的名字的是靠近左边的阶段的,而勤奋让我们走向右边的阶段。我认为,名字越往右边的阶段,给我们提供越多的清晰性。这个,同样也符合Kent Beck的观点,他的描述为“展现意义的名字”。

当我发现15行重复的代码,我把它们放入一个新方法,这时候我可能还不知道这些代码是做什么的。我把这个新方法命名为foo()。大概经过15分钟的理解,我知道了这个方法是做什么的,因此我给这个方法一个准确的名字,例如computeCost()。当我尝试给这个新方法写测试,发现这个方法比我的期待做了更多的事,我意识到它不仅仅是计算单个物品的价格,因此,我给它重命名的更精确:findItemThenComputeCost()。类似:“和”,"或",“但是”或“然后”这类的连接词一旦在方法名中的出现,表明该方法有超过一个的职责。作为结果,我很快发现我在重复的测试一些重复的,无关紧要的细节。为了删除重复的部分,我不得不将这个方法拆成两个:一个是找到单个物品,一个是计算价格。当我再认真看computeCost这个方法,它把税和轮船的费用也加入了物品的价格,这个导致我将这个行为拆分成个多个方法,每个计算物品的一部分费用。为此,我引入了更有意义的类OrderItem以及包含方法applyTo(item)的接口OrderItemCharge,以及实现了这个接口的PrinceEdwardIslandSalesTax,CanadianGoodsAndServicesTax
DomesticShipping。这些有意义的命名表达了程序的设计,比之前的computeCost()这个名字好多了。你可以在你的代码中找到很多这种命名向有意义的这个方向发展的例子。在大部分时间,我向着命名能达到准确和精确这个程度努力,然后我发现取一个有意义的名字是相当简单的。我发现清晰可以减少起一些令人误解的名字。

最后我再强调下简单设计的两个要素是:减少重复和修改坏名字。当我删除重复的部分,我往往能发现一个合适的结构,当我们修改完坏的名字,我们往往能将对代码的职责进行一个比较好的设计。

我认为这些模块化设计的原则,与你是否使用对象是可以共存的。如果你使用对象,你遵循的这些原则,即是遵循面向对象的设计原则,你不用,你遵循的是面向过程的设计的原则。(我不知道这些原则在函数式编程中是否适用,因为我使用函数式编程不够多。)

我认为,学习发现重复,删除重复,发现命名问题,以及修复命名问题的技能相当于学习任何关于面向对象的设计的技能。

简而言之,如果你掌握了删除重复,修复坏命名的技能,我可以说你掌握了面向对象的设计的技能。

如果你现在想烧掉接的旧的面向对象/面向过程的书,我不会打扰你,不过我想告诉你的是,如果有人想买,那就卖给他把。

🐋 Web 前端
Web note ad 1