何时使用继承,何时使用“仅布尔字段”?


18

在我们的Rails应用程序中,我们正在添加通知。其中一些是blocking:它们会停止添加任何资源的进度,因为缺少该资源的某些信息。

其他通知是简单通知,仅提供信息。

今天,我与团队中的另一个程序员进行了讨论。我创建了这样的继承结构:

在此处输入图片说明

但是,他希望我只是blocking在每个Notification上添加为布尔返回方法,并指定在Notification父类内阻塞的子类列表。

这些方法之间的差异不是很大。在我的方法中,不必指定此列表,以使根类保持整洁。另一方面,Notification::Blocking现在发生的特殊逻辑也不是很大。

哪种抽象更适合此问题?


11
家长班永远不应该知道孩子。为什么需要保留子类列表?
coteyr

如何将它们添加到资源上以及如何停止其进度?
null

3
为什么需要那么多通知类?在我看来,您可以创建一个通知类,然后让数据驱动操作而不是数据类型。
Trisped

1
@Trisped:是的,如果您发现自己将行为的一个方面以详尽的案例列表移到基类中,那么您就有勇气了,请承认您并没有真正为扩展设计自定义可用的基类,并将所有行为移至基类!
史蒂夫·杰索普

Answers:


35

您想避免基类了解派生类。它引入了紧密的耦合,并且使您头疼,因为您每次创建新的派生类时都必须记住要添加到列表中。

如果要在多个项目中使用此类,也将使您无法将Notification类放入可重用的程序包/程序集中。

如果您确实要使用单个基类,则解决此问题的另一种方法是在Notification基类上添加虚拟属性或方法IsBlocking。然后派生的类可以覆盖它以返回true或false。如果基类不了解派生类,则将只有一个类解决方案。


3
这个。在一个地方做决定。不要分散对哪些类在类和列表之间进行阻塞的了解。
candied_orange

这是我要做的,效果很好,并且可重用。
coteyr

13

并指定在Notification父类内部受阻的子类列表。

这看起来很奇怪,并且是一种特殊的代码味道。

如果您在类之间的行为上有差异,并且希望以相同的方式(即使用多态)对待所有这些通知,我将提供子类。


1
我认为“行为”是这里的关键:当仅是数据时,该字段应足以区分。行为是使用多态性的更好理由,但是在创建继承层次结构时应始终考虑维护复杂性。阅读en.wikipedia.org/wiki/Composition_over_inheritance
cottsak

7

与现有答案相反,我建议如果需要动态更改要使用的模式(例如,通过提供要阻止哪些类型的列表的配置文件),则布尔属性是最佳选择而且不是)。

也就是说,即使在这种情况下,更好的设计也可能是使用Decorator对象。


1

我会说,这取决于阻止通知的特殊性,尽管我首先想到的是与“ both”一起使用:

class Notification
 virtual Boolean Blocking{get return false;}

class BlockingNotification inherits Notification
 virtual overrides Boolean Blocking{get return true;}

这样,您可以使用n.Blockingn is BlockingNotification(全部使用伪代码),但是,如果您要允许一个类实现上下文相关的Blocking值,那么您将看到每次必须检查该值时,BlockingNotification该类将变为不太有用。

无论如何,我都同意您不希望基类实现Blocking必须了解派生类的其他答案。


0

而不是创建两个基类和每个基类的多个实例,而是使用bool来创建一个通知类,以指示该通知是否被阻止以及将通知传达给用户所需的任何其他信息。

这使您可以使用一组代码来处理和呈现通知,并降低代码的复杂性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.