Inheritance Anti-patterns
suggest changeImproper Inheritance
Lets say there are 2 classes class Foo
and Bar
. Foo
has two features Do1
and Do2
. Bar
needs to use Do1
from Foo
, but it doesn’t need Do2
or needs feature that is equivalent to Do2
but does something completely different.
Bad way: make Do2()
on Foo
virtual then override it in Bar
or just throw Exception
in Bar
for Do2()
public class Bar : Foo
{
public override void Do2()
{
//Does something completely different that you would expect Foo to do
//or simply throws new Exception
}
}
Good way
Take out Do1()
from Foo
and put it into new class Baz
then inherit both Foo
and Bar
from Baz
and implement Do2()
separately
public class Baz
{
public void Do1()
{
// magic
}
}
public class Foo : Baz
{
public void Do2()
{
// foo way
}
}
public class Bar : Baz
{
public void Do2()
{
// bar way or not have Do2 at all
}
}
Now why first example is bad and second is good: When developer nr2 has to do a change in Foo
, chances are he will break implementation of Bar
because Bar
is now inseparable from Foo
. When doing it by latter example Foo
and Bar
commonalty has been moved to Baz
and they do not affect each other (like the shouldn’t).