The Interface Segregation Principle states that the clients should not be forced to use the methods that they do not use.
The above image depicts the complex interface with switches and buttons for the usb to work but the end user does not care about this complexity. The end use just needs to know where to plug-in the usb for the usb to work. An Interface is a non-implementable type that specifies a public set of methods and properties that are implemented by the type that chooses to implement that interface. An Interface could also be the public interface of a class where it exposes the public methods and properties of the class. Now if some client needs only a part of the functionality then we should be able to better design the interfaces or sub-class so that the client in not forced to use what it does not need. Let us take the example of a store that takes order both online as well as in the store. In the online order the store accepts credit cards but in the store order it accepts only cash. So have an Interface IOrder as shown below:
public interface IOrder { void ProcessOrder(); void ProcessCreditCard(); }
And both the OnlineOrder class and InStoreOrder class implement this interface.
public class OnlineOrder : IOrder { public void ProcessOrder() { //Process the order placed } public void ProcessCreditCard() { //Process payment through credit card } }
public class InStoreOrder : IOrder { public void ProcessOrder() { //Process the order placed } public void ProcessCreditCard() { //Not Implemented throw new NotImplementedException(); } }
In the above implementation we are violating the Interface Segregation Principle because the InStoreOrder class implements the IOrder interface but it does not implement one of the methods ProcessCreditCard. Let’s improve the solution to follow Interface Segregation Principle. To do that we will break the IOrder interface and create another Interface IOnlineOrder which will have the ProcessCreditCard method. So now the interfaces will look like below.
public interface IOrder { void ProcessOrder(); } public interface IOnlineOrder : IOrder { void ProcessCreditCard(); }
So our existing implementations could still remain the same and new the implementation that need online part of the functionality will use the implement the required interface only.
public class OnlineOrder : IOnlineOrder { public void ProcessOrder() { //Process the order placed } public void ProcessCreditCard() { //Process payment through credit card } }
public class InStoreOrder : IOrder { public void ProcessOrder() { //Process the order placed } }