Clients should not be forced to depend upon interfaces that they do not use
Rober Martin
This principle, similar to Single Responsibility Principal, is about avoiding redundant code changes when requirements change. Following this principle will save you from changing existing classes, allows to add extra functionality with just an extra class.
We could also redefine this principle like this:
Go for more smaller interfaces instead of less bigger
Example
Lets take our common HR model which we used in other SOLID samples. Imagine there is an employee positions for Salesman and Administrator. Both Salesman and Administrator get monthly salary. But in the end of the year, Salesman gets rewarded, calculating by his annual sales. Administrator – get fixed bonus. And there we have relevant methods implemented. First lets see how it looks like in wrong way, ignoring Interface Segregation Principle:
Wrong
public interface EmployeeInterface { int getMonthlySalary(); int getAnnualSalesAmount(); int getBonus(); } public class Salesman implements EmployeeInterface { public int getMonthlySalary() {...} public int getAnnualSalesAmount(){...}; public int getBonus(){...}; } public class Administrator implements EmployeeInreface { public int getMonthlySalary() {...} public int getAnnualSalesAmount(){...}; public int getBonus(){...}; }
Here we see that there is one single interface dedicated for all types of employees. Salesman must implement method getBonus(), which is redundant for this type of employee. Administrator respectively must implement getAnnualSalesAmount() which does not make sense to him. And further more, imagine, that another method appears to be necessary for Salesman, i.e. getSalesRate(). After appending it to EmployeeInterface, Administrator class would need to implement it as well. And here we have unnecessary change of existing class.
Correct
public interface EmployeeInterface { int getMonthlySalary(); } public interface SalesmanInterface { int getAnnualSalesAmount(); } public interface AdministratorInterface { int getBonus(); } public class Salesman implements EmployeeInterface,SalesmanInterface { public int getMonthlySalary() {...} public int getAnnualSalesAmount(){...}; } public class Administrator implements EmployeeInterface,AdministratorInterface { public int getMonthlySalary() {...} public int getBonus(){...}; }
Here we have interface segregation fulfilled. Separate interfaces for Salesman and Administrator takes place. And we can use them independently from each other. Although another, general interface for both types of employees is also needed to be implemented – EmployeeInterface. Depending on your application specific, you can choose to extend interfaces as well:
public interface EmployeeInterface { int getMonthlySalary(); } public interface SalesmanInterface extends EmployeeInterface { int getAnnualSalesAmount(); } public interface AdministratorInterface extends EmployeeInterface { int getBonus(); } public class Salesman implements SalesmanInterface { public int getMonthlySalary() {...} public int getAnnualSalesAmount(){...}; } public class Administrator implements AdministratorInterface { public int getMonthlySalary() {...} public int getBonus(){...}; }
Please check for other SOLID principles in this post – SOLID Software Design Principles. Summary.