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?
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
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.
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.
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
{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With