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?
Which SOLID principle is violated in the following code? I think that LSP (Liskov Substitution Principle) is violated because the subclass B cannot be substituted into a variable of type A .
In this example, let's pretend that I first have an IPost interface with the signature of a CreatePost() method. Later on, I modify this interface by adding a new method ReadPost() , so it becomes like the IPostNew interface. This is where we violate the interface segregation principle.
A class should have only one reason to change. A common misconception about this principle is that people think it means that a class should do only one thing. This is not the case: a class can do multiple things. If not, you'd end up with classes that only have a single public method.
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.
I disagree to the fact that your example code violates the LSP. LSP is defined as followed:
Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T.
Given the two derivation from Animal, namely Dog
and Cat
and your method getAnimalNoise
you are not making decisions about some proveable property of the concrete object. Your method is deciding what noise should be returned and not the objects by there self.
So lets imagine you can set the number of legs for an animal.
Animal a = new Animal()
a.setLegFront(2);
a.setLegRear(2);
And if your Dog
overwrites this like this:
class Dog extends Animal
{
public void setFrontLegs(int legs)
{
this.frontLegs = legs;
this.rearLegs = legs + 2;
}
public void setRearLegs(int legs)
{
// do nothing here for demonstration purposes
}
}
If you now have a factory returning a Animal
Animal createAnimal()
{
return new Dog();
}
Animal a = createAnimal();
a.setFrontLegs(2);
a.setRearLegs(2);
And you call the methods setFront/setRearLegs
you are expecting the results to be 2 and 2 but in fact the result is completely different, namely 2 and 4. So this example is tightly bound to the common LSP example with squares and rectangles. But for me its a more accurate example of a violation of provable properties than in you example.
I agree with you that the other principles are also violated but for SRP I agree with @dcastro.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With