Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should these interfaces be inherited at interface level or implemented at class level?

Tags:

c#

interface

I am creating a console application for the purpose of learning the state and observer patterns. The program is based on a basic order system whereby each order can have a state (pending, ready, submitted i.e state pattern) and subscribers that are interested in receiving notifications from the order when it gets updated are notified (observer pattern).

The Order class is implementing three interfaces; IOrder, IOrderState and IObservable but I realised that instead I could have the interfaces inheriting from each other. Which approach would be better? When would you make the class implement from each of the interfaces separately instead of having say, IOrder inherit from the other two?

For example:

public class Order : IOrder, IOrderState, IObservable

or

public interface IOrder : IOrderState, IObservable

edit I may have just answered my question - am I right in thinking you would make the IOrder interface inherit from the other two interfaces if you are sure the object that will implement it (the Order class) will always need to use those methods? And if you're not sure if an interfaces methods are needed, or if other classes i.e perhaps an order that does not need to be observed by subscribers, then you would include the interfaces separately at class level?

like image 615
Theomax Avatar asked Feb 23 '14 10:02

Theomax


4 Answers

According to ISP (Interface Segregation Principle) rule, it should be that the IOrder interface implements the IOrderState, IObservable interfaces. So whichever class implements IOrder, it will also implement the other 2 interfaces.

So the 2nd case is more appropriate. i.e.

public interface IOrder : IOrderState, IObservable
like image 171
Wasif Hossain Avatar answered Oct 04 '22 21:10

Wasif Hossain


I think it really depends on the Interfaces meaning. Though in your example it doesnt make much sense to seperate those interfaces since they look too close together.

However if you can think of a case where a class only needs IOrder and not those other two, you may want to split em up.

Lets take a look on access modifiers. If you inherit the interfaces, all could possibly be public visible for example. If you only want your Orderstate and Observation internally, you have to split them up.

E.g. someone using your library should only know what is exposed by IOrder and not IOrderstate.

like image 37
CSharpie Avatar answered Oct 04 '22 20:10

CSharpie


When designing types, you have to know about use-cases, or, at least, think about them.
When creating an interface, you should think about its possible implementations. Not every class should be complemented with interface.

When every class in your library looks like this:

interface IMyClass {}
class MyClass : IMyClass {}

then this is a cause to look at type design once again. There's large probability, that your class library goes to hell. I'm have to support some legacy code now, where almost every internal class has a coupled internal interface, and this class is a single inmplementation. Honestly, I'd like to forbid my former colleague to use interfaces any more.

If you could imagine any other IOrder impelmentation, then, make IOrder interface. Otherwise, throw it away (e.g., I can't imagine two or more different IOrderState implementations).

If every IOrder must be IObservable, then inherit IOrder from IObservable. It completely depends on your use-cases.

like image 35
Dennis Avatar answered Oct 04 '22 21:10

Dennis


With your few info about your concrete use case the answer won't be very exact, but I'll try to give you some directives/hints.

Instead of a generic and common principle, I would say you need to think about your concrete scenario.

Perhaps you can ask yourself the following questions:

  • Do all IOrder consumers require to observe the order? If this is the case, IOrder should implement IObservable.

  • Do all IOrder consumers require to track orders state? If this is the case, IOrder should implement IOrderState.

Actually I would ask this kind of questions in order to determine what to do.

In the other hand, you can think about a more flexible architecture where what Order should implement can be defined by generic constraints:

public void Add<TOrder>(TOrder order) where TOrder : IOrder
{
}

But when you need to track order's state, you may do this:

public void SaveState<TOrder>(TOrder order) where TOrder : IOrder, IOrderState
{
}
like image 23
Matías Fidemraizer Avatar answered Oct 04 '22 21:10

Matías Fidemraizer