Recently in a job interview, they ask me "how to solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance". I thought on Aggregation or Composition, but i was a little confused on making an example based on that.
So I decided to leave it pending to deepen concepts later, but after investigating it did not end up forming a precise answer to that question, could someone explain me a solution or an example to this?
CodePudding user response:
Parallel Inheritance Hierarchies makes many unnecessary classes and makes code very fragile and tightly coupled.
For example, we have class Sportsman
and its Goal
's.
public abstract class Sportsman
{
public string Name { get; set; }
public abstract string ShowGoal();
}
and concrete class Footballer
:
public class Footballer : Sportsman
{
public override string ShowGoal()
{
return new FootballerGoal().Get();
}
}
and Runner
:
public class Runner : Sportsman
{
public override string ShowGoal()
{
return new RunnerGoal().Get();
}
}
Then we have their goals:
public abstract class Goal
{
public abstract string Get();
}
and its concrete classes:
public class FootballerGoal : Goal
{
public override string Get()
{
return "Score 1 goal";
}
}
And runner goal:
public class RunnerGoal : Goal
{
public override string Get()
{
return "Run 1 km";
}
}
Now, it can be seen that if we add new type of sportsman, then we need add a new class to hierarchy of Goal
.
We can try to avoid of creation of that hierarchy tree by using dependency injection and extracting method to interface.
At first, we create interface:
public interface IGoal
{
string Visit(Sportsman sportsman);
}
and then just implement it:
public class FootballerGoal : IGoal
{
public string Visit(Sportsman sportsman)
{
return "Score 1 goal";
}
}
and use it in Footballer
class:
public class Footballer : Sportsman
{
public string ShowGoal(IGoal goal)
{
return goal.Visit(this);
}
}
Now we do not have hierarchy tree and we can call it like this:
new Footballer().GetGoal(new FootballerGoal())
CodePudding user response:
The c2 wiki has a page on parallel inheritance hierarchies where ChaoKuoLin lists four possible solutions. I paraphrase them here, along with some context for each. See the original page for a full explanation including advantages, disadvantages, and examples.
- Keep the parallel hierarchies.
- When the hierarchies have separate responsibilities and each contains many methods.
- When maximum flexibility is required.
- Keep one of the hierarchies and collapse the other into a class.
- When one of the hierarchies can be reduced to a single class, for example by moving some methods to the other hierarchy.
- When one of the hierarchies contains few methods.
- Collapse the two hierarchies into one.
- When the hierarchies have similar responsibilities and each contains few methods.
- Keep a partial parallel hierarchy with the rest collapsed.
- When you want a middle ground among the previous solutions.
Another solution suggested in the wiki is Mix In and it is also suggested in How to solve parallel Inheritance in UI case?