【问题标题】:Which of the SOLID principles is violated in this class diagram在这个类图中违反了哪条 SOLID 原则
【发布时间】:2021-06-25 19:18:49
【问题描述】:

这是去年没有答案的考试之一:
[1]:https://i.stack.imgur.com/RDzz0.jpg

它显示了一个包含两个类的图表,CustomerSupplier,它们都继承自一个类 Partner。另一个类 Customer_Supplier 继承自 CustomerSupplier

问题是这种设计会违反什么 SOLID 原则。尽管进行了仔细的验证,但我找不到任何东西,并且真的很想知道。

【问题讨论】:

  • 我会怀疑 Liskov 因为这个设计中的多态性。实际上,我从不关心“原则”,尤其是对于考试成绩而言。我永远不会使用多重继承,因为它很臭。
  • 我投票重新提出这个问题,这确实很有趣。只有一个可能的答案(而且它不是 LSP),并且有完全客观的论据来确定哪个。
  • @qwerty_so Is multiple inheritance really needed? 如果你不这么认为,here a diagram 没有 MI 与 OP 具​​有相同的问题和相同的答案 ;-)
  • 或者如果 OP 正在倾听:您可以删除此问题并再次询问(我通常不建议这样做)。但这样一来,您可能会找到比关闭速度更快的人来回答。
  • 不知道为什么这也是出于“基于意见”的原因而关闭的。这不是每个人都用接口解决的钻石问题吗? @Christophe 我同意你的看法。

标签: oop uml class-diagram solid-principles


【解决方案1】:

下图是大名鼎鼎的diamond of death,在使用多重继承时一个非常微妙的问题:

学术答案

您的问题的学术答案是这种设计违反了Single Responsibility Principle。原因如下:

  • 一个类应该有一个单一的职责
  • SupplierCustomer 都有一个职责
  • Customer_Supplier 至少继承两个职责

实际上,SRP 大约是reason to change。但总体趋势是应用相同的推理:Customer_Supplier 可能必须因为 Supplier 的变化或 Customer 的变化而变化。

淘汰其他候选人

它在设计上原则上符合Open/Close Principle。每个类都可以扩展,除非证明相反,否则不需要修改它们。

类图很少足以确认或拒绝遵守Liskov Substitution Principle,因为这个原则是关于类及其子类的契约/承诺。 LSP 要求只要需要超类的对象,就可以使用子类的对象。乍一看,Customer_Supplier 可以用来代替Supplier,也可以用来代替Customer。当然,人们可以很容易地想象出一个打破这一点的类。但这同样适用于任何最简单的继承。事实是,图表中的任何内容都无法让我们假设相反的情况。

Interface Segregation Principle 也没有被违反。相反,如果客户端不需要Customer_Supplier 接口,您可以使用其中一个父类。如果您在客户端使用Customer_Supplier,可能是因为您需要完整的界面。

最后,Dependency Inversion Principle 在这里不相关。没有任何迹象表明一个类比另一个类更具体或更抽象。事实上,这些甚至都可以是抽象类。所以没有理由认为这个设计不符合“抽象不应该依赖细节。细节(具体实现)应该依赖抽象”。

学术答案是否有缺陷?

死亡钻石是一个极端的例子,经常作为例子来解释多重继承是不好的。而且多重继承很容易被滥用。但单继承和任何其他编程结构也可以。

让我们更客观一些:

  • 类应该有一个单一的职责。如果一个类从另一个类继承,那么它可能有两个责任:它自己的责任和超类的责任。另一方面,没有什么告诉我们这些职责是独立的:一个可能是另一个的子职责。
  • 因此,如果Supplier具有BusinessPartner的子责任,而Customer具有BusinessPartner的子责任,则它们都具有相同更大责任的子责任,尤其是考虑到Open /封闭原则。这意味着Customer_Supplier 最终可能仍然只是这个单一大职责的子职责。所以 SRP 完全可以得到尊重。

这不是高级计算机科学,而是基本集合论。您可以使用相同的推理来更改原因。

另一个推理可以用于更改原因:如果子类仅使用超类的公共接口(鉴于 LSP 的历史约束,这是一种稳健的做法),子类不会受到超类更改的影响超过通过其依赖的类的任何其他更改。所以改变的唯一理由仍然存在。

出于所有这些原因,我将重新制定学术答案如下:如果这种设计违反了 SOLID 原则,那么它可能只是 SRP。不过也不一定违反。

为了敲钉子,我将以 R.C. 的一句话作为结尾。发明 SRP 概念的 Martin:

这就是单一职责原则的关键所在。这个原则是关于人的。

而且这个设计并没有说明任何关于人的内容。

最后提出一个哲学问题:is multiple inheritance really needed?

【讨论】:

  • 那么,如果你参加考试,并且它是多项选择题,其中有五个 SOLID 原则中的任何一个选项加上以上都不是,那么你会选择哪一个?
  • @jaco0646 我会首先尝试记住老师在课程中对这个案例所说的内容,或者关于继承和 SRP 的其他示例。如果这还没有导致 SRP 答案,就个人而言,我会选择无
猜你喜欢
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 2018-11-13
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多