How to Solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance - oop

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?

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())
UPDATE:
There is a good article about Parallel Inheritance Hierarchies.. It proposes some ways to solve this task. Let me show the third way.
Solution 3 Collapse a hierarchy.
Pros:
Only maintain One hierarchy
Easy to maintain
Cons
Breaks SRP fairly often.
So Footballer class would like this:
public class Footballer : Sportsman
{
public override string ShowGoal()
{
return new FootballerGoal().Get();
}
public string GetGoal()
{
return "Score 1 goal";
}
}
And Runner class would like this:
public class Runner : Sportsman
{
public override string ShowGoal()
{
return new RunnerGoal().Get();
}
public string GetGoal()
{
return "Run 1 km";
}
}

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?

Related

How to simply introduce a new method on a large subset of classes implementing an interface?

I have an interface, say IVehicle, which is implemented in 100s of classes, some of them are variety of 4 wheeler and some are two wheeler dervied types.
I need to introduce a new method for all the 4 wheeler classes, lets say there are 50 of them. My challenge is to reduce the effort as much as I can.
I suggested, to introduce a new interface / abstract class with a method definition. But this require to change every 4 wheeler class declaration and extend with an extra parent.
Is there any possible way?
If you really want to avoid changing all those classes and want a solution that can be considered to be OO, one thing you can do is decorate those classes where they are used and need this extra behaviour.
I'll use C# for example code as you mentioned you're looking for C#/Java solution.
interface IVehicle
{
void DoThisNormalThing();
// ...
}
interface IBetterVehicle : IVehicle
{
void DoThisNeatThing();
}
class FourWheelVehicle : IVehicle
{
public void DoThisNormalThing()
{
// ...
}
// ...
}
class BetterFourWheelVehicle : IBetterVehicle
{
private readonly _vehicle;
public BetterFourWheelVehicle(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void DoThisNormalThing()
{
_vehicle.DoThisNormalThing();
}
public void DoThisNeatThing()
{
// ...
}
// ...
}
Then usage:
var vehicle = new FourWheelVehicle();
var betterVehicle = new BetterFourWheelVehicle(vehicle);
betterVehicle.DoThisNeatThing();
This can be done using extension methods as well (and would result in a little less code and fewer allocated objects), but as this question is tagged with [oop] I wouldn't say extension methods are an OO construct. They're much more aligned with procedural style as they turn your objects into bags of procedures.

Do we need interfaces for dependency injection?

I have an ASP.NET Core application. The application has few helper classes that does some work. Each class has different signature method. I see lot of .net core examples online that create interface for each class and then register types with DI framework. For example
public interface IStorage
{
Task Download(string file);
}
public class Storage
{
public Task Download(string file)
{
}
}
public interface IOcr
{
Task Process();
}
public class Ocr:IOcr
{
public Task Process()
{
}
}
Basically for each interface there is only one class. Then i register these types with DI as
services.AddScoped<IStorage, Storage>();
services.AddScoped<IOcr,Ocr>();
But i can register type without having interfaces so interfaces here look redundant. eg
services.AddScoped<Storage>();
services.AddScoped<Ocr>();
So do i really need interfaces?
No, you don't need interfaces for dependency injection. But dependency injection is much more useful with them!
As you noticed, you can register concrete types with the service collection and ASP.NET Core will inject them into your classes without problems. The benefit you get by injecting them over simply creating instances with new Storage() is service lifetime management (transient vs. scoped vs. singleton).
That's useful, but only part of the power of using DI. As #DavidG pointed out, the big reason why interfaces are so often paired with DI is because of testing. Making your consumer classes depend on interfaces (abstractions) instead of other concrete classes makes them much easier to test.
For example, you could create a MockStorage that implements IStorage for use during testing, and your consumer class shouldn't be able to tell the difference. Or, you can use a mocking framework to easily create a mocked IStorage on the fly. Doing the same thing with concrete classes is much harder. Interfaces make it easy to replace implementations without changing the abstraction.
Does it work? Yes. Should you do it? No.
Dependency Injection is a tool for the principle of Dependency Inversion : https://en.wikipedia.org/wiki/Dependency_inversion_principle
Or as it's described in SOLID
one should “depend upon abstractions, [not] concretions."
You can just inject concrete classes all over the place and it will work. But it's not what DI was designed to achieve.
No, we don't need interfaces. In addition to injecting classes or interfaces you can also inject delegates. It's comparable to injecting an interface with one method.
Example:
public delegate int DoMathFunction(int value1, int value2);
public class DependsOnMathFunction
{
private readonly DoMathFunction _doMath;
public DependsOnAFunction(DoMathFunction doMath)
{
_doMath = doMath;
}
public int DoSomethingWithNumbers(int number1, int number2)
{
return _doMath(number1, number2);
}
}
You could do it without declaring a delegate, just injecting a Func<Something, Whatever> and that will also work. I'd lean toward the delegate because it's easier to set up DI. You might have two delegates with the same signature that serve unrelated purposes.
One benefit to this is that it steers the code toward interface segregation. Someone might be tempted to add a method to an interface (and its implementation) because it's already getting injected somewhere so it's convenient.
That means
The interface and implementation gain responsibility they possibly shouldn't have just because it's convenient for someone in the moment.
The class that depends on the interface can also grow in its responsibility but it's harder to identify because the number of its dependencies hasn't grown.
Other classes end up depending on the bloated, less-segregated interface.
I've seen cases where a single dependency eventually grows into what should really be two or three entirely separate classes, all because it was convenient to add to an existing interface and class instead of injecting something new. That in turn helped some classes on their way to becoming 2,500 lines long.
You can't prevent someone doing what they shouldn't. You can't stop someone from just making a class depend on 10 different delegates. But it can set a pattern that guides future growth in the right direction and provides some resistance to growing interfaces and classes out control.
(This doesn't mean don't use interfaces. It means that you have options.)
I won't try to cover what others have already mentioned, using interfaces with DI will often be the best option. But it's worth mentioning that using object inheritance at times may provide another useful option. So for example:
public class Storage
{
public virtual Task Download(string file)
{
}
}
public class DiskStorage: Storage
{
public override Task Download(string file)
{
}
}
and registering it like so:
services.AddScoped<Storage, DiskStorage>();
Without Interface
public class Benefits
{
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : Benefits
{
private readonly Benefits BT;
public Teacher(Benefits _BT)
{ BT = _BT; }
public void TeacherBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
public class Student : Benefits
{
private readonly Benefits BS;
public Student(Benefits _BS)
{ BS = _BS; }
public void StudentBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
here you can see benefits for Teachers is accessible in Student class and benefits for Student is accessible in Teacher class which is wrong.
Lets see how can we resolve this problem using interface
With Interface
public interface IBenefitForTeacher
{
void BenefitForTeacher();
}
public interface IBenefitForStudent
{
void BenefitForStudent();
}
public class Benefits : IBenefitForTeacher, IBenefitForStudent
{
public Benefits() { }
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : IBenefitForTeacher
{
private readonly IBenefitForTeacher BT;
public Teacher(IBenefitForTeacher _BT)
{ BT = _BT; }
public void BenefitForTeacher()
{
BT.BenefitForTeacher();
}
}
public class Student : IBenefitForStudent
{
private readonly IBenefitForStudent BS;
public Student(IBenefitForStudent _BS)
{ BS = _BS; }
public void BenefitForStudent()
{
BS.BenefitForStudent();
}
}
Here you can see there is no way to call Teacher benefits in Student class and Student benefits in Teacher class
So interface is used here as an abstraction layer.

Avoid adding/extending methods to interface

I have a scenario , where my current interface looks like
public interface IMathematicalOperation
{
void AddInt();
}
After an year i expect the interface to be extended with AddFloat method and also expect 100 users already consuming this interface. When i extend the interface with a new method after an year i don't want these 100 classes to get changed.
So how can i tackle this situation ? Is there any design pattern available already to take care of this situation ?
Note: i understand that i can have a abstract class which implement this interface and make all the methods virtual , so that clients can inherit from this class rather than the interface and override the methods . When i add a new method only the abstract class will be changed and the clients who are interested in the method will override the behavior (minimize the change) .
Is there any other way of achieving the same result (like having a method named Add and based on certain condition it will do Float addition or Integer addition) ?
Edit 1:
The new method gets added to the interface also needs to be called automatically along with the existing methods(like chain of responsibility pattern).
There are at least two possible solution I can think of:
Derive your new interface from your old interface
public interface IMathematicalOperation
{
void AddInt();
}
public interface IFloatingPointMathematicalOperation : IMathematicalOperation
{
void AddFloat();
}
Have simply a parallel interface which contains the new method and have all classes which need the new interface derive from it
I'd suggest the second solution, since I don't understand why you would want an established interface to change.
I encountered a similar issue some time ago and found the best way was not to try and extend an existing interface, but to provide different versions of the interface with each new interface providing extra functionality. Over time I found that was not adding functionality on a regular basis, may once a year, so adding extra interfaces was never really an issue.
So, for example this is your first version of the interface:
public interface IMathematicalOperation
{
void AddInt();
}
This interface would then be implemented on a class like this:
public class MathematicalOperationImpl : IMathematicalOperation
{
public void AddInt()
{
}
}
Then when you need to add new functionality, i.e. create a version 2, you would create another interface with the same name, but with a "2" on the end:
public interface IMathematicalOperation2 : IMathematicalOperation
{
void AddFloat();
}
And the MathematicalOperationImpl would be extended to implement this new interface:
public class MathematicalOperationImpl : IMathematicalOperation, IMathematicalOperation2
{
public void AddInt()
{
}
public void AddFloat()
{
}
}
All of your new/future clients could start using the version 2 interface, but your existing clients would continue to work because they will only know about the first version of the interface.
The options provided are syntactically viable but then, as is obvious, they won't apply to any previous users.
A better option would be to use the Visitor pattern
The pattern is best understood when you think about the details of OO code
this.foo(); // is identical to
foo(this);
Remember that there is always a hidden 'this' parameter passed with every instance call.
What the visitor pattern attempts to do is generalize this behavior using Double dispatch
Let's take this a hair further
public interface MathematicalOperation
{
void addInt();
void accept(MathVisitor v);
}
public interface MathVisitor {
void visit(MathematicalOperation operation);
}
public class SquareVistor implements MathVisitor {
void visit(MathematicalOperation operation) {
operation.setValue(operation.getValue() * 2);
}
}
public abstract class AbstractMathematicalOperation implements MathematicalOperation {
public void accept(MathVisitor f) {
f.visit(this); // we are going to do 'f' on 'this'. Or think this.f();
}
}
public class MyMathOperation extends AbstractMathematicalOperation {
}
someMathOperation.visit(new SquareVisitor()); // is now functionally equivalent to
someMathOperation.square();
The best bet would be for you to roll-out your initial interface with a visitor requirements, then immediately roll-out an abstract subclass that gives this default implementation so it's cooked right in (As the above class is). Then everyone can just extend it. I think you will find this gives you the flexibility you need and leaves you will the ability to work with legacy classes.

Design a Furniture class with classes like WoodChair, WoodTable etc

This is an OOD based interview question:
There is a Furniture class and has derived classes like WoodChair, WoodTable, SteelChair, SteelTable. Interviewer wanted to add more number of classes like ironchair,irontable etc; How should we do that. The design is not yet published and we are free to modify the entire sutff given.
I thought that since we're basically building types of furniture we should use a builder pattern here with Furniture class with properties like type (chair/table) and make(iron/wood) etc. Then we'd have an interface Builder with functions like: buildLegs(..), buildSurface(..) and sub-classes like ChairBuilder, TableBuilder and a Director class to instantiate all of them. We could add as many new types of Furniture of any make and construct a builder class for them without affecting existing design.
After reading Builder Vs Decorator pattern I was sure that I'm not supposed to use Decorator pattern here. But is Builder also ok? Is it an overkill?
Also, I'm not sure how to deal with the make of the furniture. Would adding a feature of type enum for the make be enough? [steel, iron, wood] The make doesn't really add any new behavior to the furniture items.
It looks like something needs to be refactored in the existing classes, which may also help avoiding creating a new class for every one of the need that arise in the future. This depends entirely on the context though: an inventory application needs a radically different model of a chair than a software that needs to display a chair in 3d. How do you know? Ask the interviewer, then you will know where they want you to go.
Boring case: a Chair has some common behavior/data that can be refactored out in a different class, same thing for Table. Now how do you choose to represent the material? Again, it depends on the domain, ask the interviewer. It is also a matter of the language you are using: does your language of choice support multiple inheritance? Do you need (or want) to use multiple inheritance at all? It may make sense to favor composition over inheritance. Why would you go one way or the other? Do you even need a class to represent this piece of information?
How should we do that.
Ask the interviewer, they will guide you to the solution. There is no single correct answer to a problem so broadly formulated, they want you to ask questions and see how you think. That said, as broad as the question is, the way it is formulated may be a hint that you should refactor something in order to avoid having to create a class for every new combination of furniture and material.
Possible solutions:
No need for Table/Chair/Bed to inherit from Furniture: a class Furniture with a property for the piece of furniture and a property for the material.
Classes for Table, Chair, Bed, whatever with a property for the material. The complexity of how the material is represented depends on how this information have to be modeled: it could be a string, or a Class (Wood, Iron, Steel) implementing an IMaterial interface.
Probably, i was use Abstract Factory: WoodFurntiture, SteelFurniture, IronFurniture.
Each Factory know How to make chair, table.
Inside you can use (if you need) other DP, but for a now, i do not see any needs for it
Code:
namespace Furniture
{
class Program
{
static void Main(string[] args)
{
IFurnitureFactory factory = new WoodFurnitureFactory();
IFurniture chair = factory.GetChair();
}
}
public interface IFurniture { }
public class WoodChair : IFurniture { }
public class WoodTable : IFurniture { }
public class SteelChair : IFurniture { }
public class SteelTable : IFurniture { }
public class IronChair : IFurniture { }
public class IronTable : IFurniture { }
public interface IFurnitureFactory
{
IFurniture GetChair();
IFurniture GetTable();
}
public class WoodFurnitureFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new WoodChair();
}
public IFurniture GetTable()
{
return new WoodTable();
}
}
public class IronFurnitureFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new IronChair();
}
public IFurniture GetTable()
{
return new IronTable();
}
}
public class SteeFurniturelFactory : IFurnitureFactory
{
public IFurniture GetChair()
{
return new SteelChair();
}
public IFurniture GetTable()
{
return new SteelTable();
}
}
}

When is an "interface" useful?

OOP interfaces.
In my own experience I find interfaces very useful when it comes to design and implement multiple inter-operating modules with multiple developers. For example, if there are two developers, one working on backend and other on frontend (UI) then they can start working in parallel once they have interfaces finalized. Thus, if everyone follows the defined contract then the integration later becomes painless. And thats what interfaces precisely do - define the contract!
Basically it avoids this situation :
Interfaces are very useful when you need a class to operate on generic methods implemented by subclasses.
public class Person
{
public void Eat(IFruit fruit)
{
Console.WriteLine("The {0} is delicious!",fruit.Name);
}
}
public interface IFruit
{
string Name { get; }
}
public class Apple : IFruit
{
public string Name
{
get { return "Apple"; }
}
}
public class Strawberry : IFruit
{
public string Name
{
get { return "Strawberry"; }
}
}
Interfaces are very useful, in case of multiple inheritance.
An Interface totally abstracts away the implementation knowledge from the client.
It allows us to change their behavior dynamically. This means how it will act depends on dynamic specialization (or substitution).
It prevents the client from being broken if the developer made some changes
to implementation or added new specialization/implementation.
It gives an open way to extend an implementation.
Programming language (C#, java )
These languages do not support multiple inheritance from classes, however, they do support multiple inheritance from interfaces; this is yet another advantage of an interface.
Basically Interfaces allow a Program to change the Implementation without having to tell all clients that they now need a "Bar" Object instead of a "Foo" Object. It tells the users of this class what it does, not what it is.
Example:
A Method you wrote wants to loop through the values given to it. Now there are several things you can iterate over, like Lists, Arrays and Collections.
Without Interfaces you would have to write:
public class Foo<T>
{
public void DoSomething(T items[])
{
}
public void DoSomething(List<T> items)
{
}
public void DoSomething(SomeCollectionType<T> items)
{
}
}
And for every new iteratable type you'd have to add another method or the user of your class would have to cast his data. For example with this solution if he has a Collection of FooCollectionType he has to cast it to an Array, List or SomeOtherCollectionType.
With interfaces you only need:
public class Foo<T>
{
public void DoSomething(IEnumerable<T> items)
{
}
}
This means your class only has to know that, whatever the user passes to it can be iterated over. If the user changes his SomeCollectionType to AnotherCollectionType he neither has to cast nor change your class.
Take note that abstract base classes allow for the same sort of abstraction but have some slight differences in usage.