INTRODUCTION
I work on my master thesis about inheritance problems and work out some indicators which show that an inheritance problem exist.
Like the following example:
EXAMPLE
public static String getAnimalNoise(Animal animal) {
if (animal instanceof Dog)
return "Woof";
if (animal instanceof Cat)
return "Miau";
return "";
}
The method returns the String "Woof"
if the given Animal instance is a Dog
and "Miau"
if it is a Cat
. The empty string because some animals make no noises at all.
So the correct solution for that should be use polymorphism with a getNoise
Method in the Animal class.
I have analysed different indicators of inheritance problems and want to say if some of them violates a SOLID Principle.
I thought the example above violates the:
But i'm not really sure whether it is true for all.
I thought:
PRINCIPLE VIOLATIONS
SRP Violation
Because conditional statements at all violates the SRP, because like the switch case statement or more than one if-else statement are consider more than one responsibility.
It exists two cases so there are more than one reason to change the method.
OCP Violation
Because if a new animal is added a new case must be added to the method so the Method is not close for modifications.
LSP VIOLATION
Each branch executes different actions dependent of the animal sub type. Which i think violates the LSP ?! I know the example of the rectangle and square and the getArea but these example i thought fits also to the violation.
DIP VIOLATION
The conditional statements take dependency that means the statements are dependent on details and not on abstractions which violates the DIP.
QUESTION:
So the Question is, for the given example, are the given principles really violated and is the reasoning correct?
SRP Because conditional statements at all violates the SRP, because like the switch case statement or more than one if-else statement are consider more than one responsibility. It exists two cases so there are more than one reason to change the method.
I strongly disagree. The SRP is meant to be interpreted with a pinch of salt. Read Uncle Bob's article on it here - he coined this principle.
I'll quote the important bits:
What defines a reason to change?
This principle is about people.
When you write a software module, you want to make sure that when changes are requested, those changes can only originate from a single person, or rather, a single tightly coupled group of people representing a single narrowly defined business function. You want to isolate your modules from the complexities of the organization as a whole, and design your systems such that each module is responsible (responds to) the needs of just that one business function.
[...] as you think about this principle, remember that the reasons for change are people. It is people who request changes. And you don't want to confuse those people, or yourself, by mixing together the code that many different people care about for different reasons.
OCP Because if a new animal is added a new case must be added to the method so the Method is not close for modifications.
Correct. The method assumes a specific set of implementations, and would not be able to handle new ones without being modified.
LSP Each branch executes different actions dependent of the animal sub type. Which i think violates the LSP ?!
It violates the LSP, but for a different reason. If i were to pass in a giraffe, I would get an unexpected result, an empty string. Which means the method is not correct for any subtype of Animal
.
DIP The conditional statements take dependency that means the statements are dependent on details and not on abstractions which violates the DIP.
Technically true, but this is just a side-effect of violating the other two principles above. It's not really the core of the problem.
Remember that principles are not rules, so don't be too strict/literal when interpreting them. Pragmatism and understanding why a principle is needed are key.