Home > front end >  How to Solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance
How to Solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance

Time:02-25

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.

  1. Keep the parallel hierarchies.
    • When the hierarchies have separate responsibilities and each contains many methods.
    • When maximum flexibility is required.
  2. 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.
  3. Collapse the two hierarchies into one.
    • When the hierarchies have similar responsibilities and each contains few methods.
  4. 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?

  • Related