不要用模式命名类。大部分

2020-08-23 20:13:01

我第一次听说这件事是因为在计算机科学中只有两件难事:高速缓存失效、命名事物和1-off-by-one错误。

我把这句话传了很多年,后来才意识到那个差一点的错误是个笑话。

我是如此直言不讳,这让我很痛苦。我承认这一点,以防你也感到痛苦。例如,双关语从我头上飞过,我说的任何话都很可能是无意的。我不相信下面的课文里有任何双关语--但是我怎么知道呢?

我一直听说在类名中最好避免使用模式名。就像人们经常做的那样,我在没有真正检查的情况下就盲目崇拜了这条规则。我自己习惯性地遵守它,并在我的OOD课程上教给人们它,但直到最近,我还不能清楚地表达出令人信服的辩护理由。

但是后来,在写第二版99瓶OOP的时候,我把它弄坏了。我创建了一个名称包含模式名称的新类。我这么做是因为我觉得这样做是对的。

我非常相信以对代码的感觉为指导,但在写一本书时,人们不能只说,好的,现在就这么做,因为我作为作者,觉得你应该这样做。尊重读者需要投入真诚的努力,将关于代码的感受拖到阳光下,并至少尝试用令人信服的语言来证明它们的合理性。

下面我已经包括了书中的摘录,我在书中尝试了这样的说服力。摘录解释了类名称中没有模式名称规则的用途,并为它的用途进行了辩护。

我围绕这条规则制作了一份时事通讯,不仅是因为我相信它很有用,还因为我最初试图解释它时,暴露了我理解上的深洞。这是一个启示。如果我没有在写一本书,我可能会永远挥手绕过我知识中的这些空白。

在继续摘录之前,这里有一些背景来引导你。在书中的这一点上:

该代码包含一个CountdownSong类,该类注入了诗句模板角色的玩家。

BottleVerse是唯一扮演这个角色的类。它被用作CountdownSong中的默认诗句模板。

我正在为CountdownSong编写测试,并且刚刚决定创建一个新的诗句模板角色的玩家,以便在这些测试期间注入使用。

下面的摘录还提到了BottleNumber类。这个类包装一个数字以添加瓶装行为。

上面的VerseFake类非常适合您的需要,尽管必须承认它毫无悔意地违反了几个常见的编程规则。

首先,第8章建议您将域行为放在实例上。该类违反了该规则;它的行为属于类/静态一端。

接下来,还有一条尚未提及的面向对象编程规则,它禁止在类名中使用模式名。上面的单词";false";指的是一种测试模式,因此将该类命名为VerseFake违反了该规则。

先做假的东西。您可能熟悉设计模式的概念,设计模式是对常见软件问题的命名、可重用的解决方案。模式名称充当通向大创意的捷径,使程序员能够快速而精确地进行交流。模式思维对软件设计的影响如此之大,以至于大多数程序员都熟悉许多模式。例如,您可能听说过Decorator、Adapter、Enumererator等等,即使您对它们的一些定义的细节不太清楚。

因为模式名非常有意义,所以很容易将它们放在类名中。例如,您可以使用Decorator模式将一个数字包含在添加额外职责的新类中。起初,NumberDecorator似乎是一个很好的结果名称。在类的名称中包含模式名称的问题在于,这会让您感觉创建了一个有用的名称,而实际上并没有这样做。模式名称通常不会反映应用程序中的概念。将它们附加到类名中会用程序员特有的词污染您的域,并绕过搜索添加语义的名称。包含模式的类名是一个信号,表明您在命名这个难题上放弃得太早了。

类名应该反映域中的概念,而不是用来创建它们的模式。与您在第4章中给这个类起的更丰富的名称BottleNumber相比,NumberDecorator是如此抽象,以至于毫无意义。未来的读者不会在意这个类是用装饰创建的,但他们会感激地知道,这是一种瓶装的数字。

Gerard Meszaros的xUnit Test Patterns一书标准化了用于简化测试的一组对象的模式名称。TestDouble是他对所有模式的通用名称。在TestDouble中,他进一步描述了Dummy、Stub、Spy、Mock、False和Temporary Test Stub模式。

Meszaros将FAKE定义为TestDouble,该TestDouble提供您实际正在进行单元测试的类所需的协作者的轻量级实现。赝品是一件普通的古老物品,不涉及魔法测试。在本例中,新的VerseFake类是诗句模板角色的真正玩家;它被称为假的,因为它只在测试期间使用。BottleVerse在生产中扮演着诗歌模板的角色。VerseFake就是为了在瓶子单元测试中扮演这个角色而创建的。

结果是FAKE是模式的名称,所以VerseFake违反了don';t-include-pattern-names-in-class-names规则。

规则的存在是为了省钱,VerseFake中断的两个规则主要是为了在生产代码中节省资金;它们在为简化测试而创建的代码中可能不太适用。例如,VerseFake的目的是伪造诗歌模板的角色。在这种情况下,VerseFake可能是最能揭示意图的名称。如果您最终需要许多不同种类的赝品,您可能需要在它们的名称中添加额外的限定符(SimpleVerseFake、ComplicatedVerseFake),但是单词";false&34;仍然会在您的测试领域中增加意义。

同样,重要的是生产代码的形状不能干扰您更改它的能力。PUT-domain-Behavior-On-Instance规则实现了这一目标。然而,在测试中,你不太关心保持假货的可变性,而更感兴趣的是直接传达它的责任。将行为放在类或静态方法中可以简化VerseFake中的代码,但会降低代码的适应性。这是您将乐于在仅由测试使用的代码中做出的权衡。

我被那个解释说服了,我希望你也是。现在我理解了,类名称中没有模式名称规则似乎既简单又不可避免。

更深一层的问题是,直到我不得不写一份解释时,我才真正理解了这条规则--相信我,我早期的尝试既不简短,也不令人信服。以上是我在办公室里走了几天,喃喃自语,摸索洞察力的结果。

这对货运并不一定是坏事--这是一条规则。大多数上升到货物崇拜能力级别的规则实际上是相当合理的,即使您不完全理解它们的微妙之处,遵循它们也可能会改进您的代码。

然而,如果您理解规则的基本目的,您将从规则中获得更多价值。更好的是,了解它的真正目的可以让你在决定破坏它时为自己辩护。

有两种编程语言(Ruby和JavaScript)和两种饮料(啤酒和牛奶)的单独书籍,今年秋天还会有一个免费的PHP升级。

我很高兴读完了这一版,现在我要把这份欢呼传递给你。

注:已经拥有这本书的读者应该最近收到了自己的个人升级优惠券。

如果您计划升级,记得在9月7日到期前使用这张优惠券,如需密码提醒,请发邮箱至Ping [email protected]