1

This is one of the past year's exams that have no answers:
[1]: https://i.stack.imgur.com/RDzz0.jpg

It shows a diagram with two classes, Customer and Supplier, inheriting both from a class Partner. Another class Customer_Supplier inherits from both, Customer and Supplier.

The question asks what SOLID principle this design would violate. Despite attentive verification, I could not find any, and would really like to know.

Christophe
  • 68,716
  • 7
  • 72
  • 138
Omar Walid
  • 25
  • 3
  • I would suspect Liskov because of the polymorphism in this design. Actually I never cared a bit about "principles" especially if they are for test scores. I never would use multiple inheritance because it just stinks. – qwerty_so Jun 25 '21 at 20:56
  • I vote to reopen this question, which is indeed interesting. There is only one answer possible (and it's not LSP), and there are completely objective arguments to determine which. – Christophe Jun 27 '21 at 15:41
  • @qwerty_so [Is multiple inheritance really needed?](https://www.stroustrup.com/bs_faq2.html#multiple) and if you don't think so, [here a diagram](https://imgur.com/5bI4Xif) without MI with the same question and same answer than OP ;-) – Christophe Jun 27 '21 at 16:14
  • @Christophe Ok, I voted. But it takes more to agree... – qwerty_so Jun 27 '21 at 19:50
  • @qwerty_so thank you for your understanding! let's be patient – Christophe Jun 27 '21 at 21:03
  • 1
    Or maybe if the OP is listening: you could delete this question and ask it once again (a procedure I usually do not suggest). But that way you might find someone to answer more quickly than it's been closed. – qwerty_so Jun 28 '21 at 07:20
  • 1
    No idea why was this closed that too for a reason "opinion based".. Ain't a diamond problem that everyone solves with interfaces? @Christophe I agree with you. – Nikhil Vartak Jun 30 '21 at 23:08
  • @NikhilVartak great! If you vote to reopen the question, we get a chance to answer. It's next to "Share", "Edit", under the question.... but it's not available on the phone app. – Christophe Jun 30 '21 at 23:36
  • @Christophe done and it's open now – Nikhil Vartak Jul 01 '21 at 11:11
  • Not sure which "principle" is violated but some popular OO langs simply don't support multiple inheritance so it would be impossible to implement the model as described. `Partner`, `Supplier` & `Customer` would have to be interfaces and reuse would happen through composition most likely e.g. `CustomerSupplier implements Supplier, Customer { private Supplier supplier; private Customer customer; ... interfaces impl }`. – plalx Jul 01 '21 at 17:17
  • @NikhilVartak thank you very much :-) – Christophe Jul 01 '21 at 21:50
  • @plalx the same question could be asked for [this diagram](https://imgur.com/5bI4Xif) with interfaces and without multiple inheritance. Btw is there really a big difference between a Java `interface` and a pure abstract C++ class? – Christophe Jul 01 '21 at 21:58

1 Answers1

2

The following diagram is the famous diamond of death, a very delicate problem when working with multiple inheritance:

enter image description here

The academic answer

The academic answer to your question is that this design violates the Single Responsibility Principle. The reasoning is the following:

  • A class should have a single responsibility
  • Supplier and Customer both have a single responsibility
  • Customer_Supplier inherits of at least two responsibilities

In reality, the SRP is about reason to change. But the general tendency is to apply the same reasoning: Customer_Supplier might have to change because of changes in Supplier or changes in Customer.

Elimination of the other candidates

It is in principle compliant with the Open/Close Principle by design. Each class could be extended, and unless the contrary is proven, there is no need to modify them.

A class diagram is rarely sufficient to confirm or deny compliance with the Liskov Substitution Principle, since this principle is about the contracts/promises of the classes and their subclasses. LSP requires that an object of the subclass can be used whenever an object of the superclass is expected. At first sight, a Customer_Supplier could be used instead of a Supplier, as well as instead of a Customer. Of course, one could easily imagine a class that breaks this. But this is equally true with any of the simplest inheritance. The fact is that nothing in the diagram lets us assume the opposite.

The Interface Segregation Principle is not violated either. On contrary, if a client does not need the Customer_Supplier interface, you could use one of the parent classes. If you use the Customer_Supplier in a client, it's probably because you need the full interface.

Finally, the Dependency Inversion Principle is not relevant here. Nothing indicates that one class is more concrete or more abstract than the other. In fact, these could even all be abstract classes. So there is no reason to think that this design does not comply with "Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions".

Is the academic answer is flawed?

The diamond of death is an extreme case that is often given as example to explain that multiple inheritance would be bad. And multiple inheritance can easily be misused. But so can be single inheritance and any other programming construct.

Let's bring in some more objectivity:

  • Classes should have a single responsibility. If a class inherits from another it may then have two responsibilities: its own and the responsibility of the superclass. On the other side, nothing tells us that these responsibilities are independent: one could be a sub-responsibility of the other.
  • Consequently, if Supplier has a sub-responsibility of BusinessPartner, and Customer has a sub-responsibility of BusinessPartner, they both have the sub-responsibilities of the same larger responsibility, especially considering the Open/Closed principle. This means that Customer_Supplier could in the end still just be a sub-responsibility of this single large responsibility. So SRP could perfectly be respected.

This is not advanced computer science, but basic set theory. You can use the same reasoning for the reason to change.

Another reasoning can be used for reason to change: if the subclass uses only the public interface of the superclass (which is a robust practice in view of LSP's history constraint) the subclass would not be impacted by changes to the superclass more than by any other change of a class that its dependent uppon. So the single reason to change could still hold.

For all these reasons, I'd reformulate the academic answer as follows: if this design would violate a SOLID principle, it could be only the the SRP. Nevertheless it does not necessarily violate it.

And to hammer the nail, I'll conclude with a quote from R.C. Martin who invented the SRP concept:

And this gets to the crux of the Single Responsibility Principle. This principle is about people.

And this design does not say anything about people.

And to finish with a philosophical question: is multiple inheritance really needed?

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • So if you were taking the exam, and it was multiple choice with the options of any of the five SOLID principles plus none-of-the-above, then which would you select? – jaco0646 Jul 02 '21 at 03:21
  • @jaco0646 I would first try to remember what the teacher said about this case in course, or about other examples with inheritance and SRP. If this does not already lead to an an SRP answer, personally, I would chose None – Christophe Jul 02 '21 at 06:23