an official definition
The Interface Segregation Principle (Interface Segregation Principle), also known as the ISP principle, is officially defined as:
- Clients should not be forced to depend upon interfaces that they don't use.
(client should not depend on interfaces it doesn't need) - The dependency of one class to another one should depend on the smallest possible
interface. (The dependencies between classes should be established on the smallest interface)
basic introduction
In layman's terms, don't define too many methods in an interface, the interface should be as detailed as possible
Two case presentations
Suppose there is such a case scenario. Now there is an interface knife. Given that he has three abilities, he can cut apples, tomatoes, and potatoes. Two classes Chef Zhang and Chef Li have these abilities respectively. There is a fruit shop class. Suppose It needs Master Zhang to cut apples and tomatoes, while another vegetable store needs Master Li to cut tomatoes and potatoes
common plan
public class SegregationDemo { public static void main(String[] args) { //fruit shop new FruitShop().cutApple(new CookZhang()); new FruitShop().cutTomato(new CookZhang()); //Vegetable store new VegetableShop().cutTomato(new CookLi()); new VegetableShop().cutPotato(new CookLi()); } } // Define the interface knife interface Knife { //ability to slice apples void cutApple(); //ability to cut tomatoes void cutTomato(); //ability to cut potatoes void cutPotato(); } //Chef Zhang class CookZhang implements Knife { @Override public void cutApple() { System.out.println("Chef Zhang is cutting apples"); } @Override public void cutTomato() { System.out.println("Chef Zhang is cutting tomatoes"); } @Override public void cutPotato() { System.out.println("Chef Zhang is cutting potatoes"); } } //Lee Chef Class class CookLi implements Knife { @Override public void cutApple() { System.out.println("Chef Li is cutting apples"); } @Override public void cutTomato() { System.out.println("Chef Li is cutting tomatoes"); } @Override public void cutPotato() { System.out.println("Chef Li is cutting potatoes"); } } /*Suppose there is such a case scenario, now there is an interface knife, given that he has three capabilities, can cut apples, tomatoes, potatoes, two classes Chef and Chef Li have these abilities respectively. There is a fruit store class, assuming that Master Zhang is needed to cut apples and tomatoes, and another vegetable store class needs Master Li is here to cut tomatoes and potatoes*/ //fruit shop class FruitShop { // Pass the interface type as a parameter public void cutApple(Knife knife) { knife.cutApple(); } public void cutTomato(Knife knife) { knife.cutTomato(); } } //Vegetable store class VegetableShop { public void cutTomato(Knife knife) { knife.cutTomato(); } public void cutPotato(Knife knife) { knife.cutPotato(); } }
case analysis
1. VegetableShop uses two methods in Knife, and the same is true for FruitShop
2. CookZhang and CookLi respectively implement the Knife interface. Knifes is not the smallest interface for CookZhang and CookLi.
In other words, CookZhang and CookLi must implement methods they don't need. Caused this class to be coupled
This violates the interface segregation principle (dependencies between classes should be established on the smallest interface)
solution
solution
According to the principle of interface isolation, we split Knife into three independent interfaces, isn't it all right?
step:
- Split Knife into three independent interfaces: AppleKnife, TomatoKinfe, and PotatoKnife
- CookZhang (Zhang chef class) implements AppleKnife, TomatoKinfe
- CookLi (Lee cook class) implements TomatoKinfe, PotatoKnife
- FruitShop (fruit shop class) cutApple method and cutTomato method are respectively passed to AppleKnife and TomatoKinfe
- VegetableShop (vegetable shop class) cutTomato method and cutPotato method are respectively passed to TomatoKinfe and PotatoKnife
public class SegregationDemo { public static void main(String[] args) { //fruit shop new FruitShop().cutApple(new CookZhang()); new FruitShop().cutTomato(new CookZhang()); //Vegetable store new VegetableShop().cutTomato(new CookLi()); new VegetableShop().cutPotato(new CookLi()); } } //Example interface segregation principle // Split interface knife into three separate interfaces interface AppleKnife { //ability to slice apples void cutApple(); } interface TomatoKinfe{ //ability to cut tomatoes void cutTomato(); } interface PotatoKnife{ //ability to cut potatoes void cutPotato(); } //Chef Zhang class CookZhang implements AppleKnife,TomatoKinfe { @Override public void cutApple() { System.out.println("Chef Zhang is cutting apples"); } @Override public void cutTomato() { System.out.println("Chef Zhang is cutting tomatoes"); } } //Lee Chef Class class CookLi implements TomatoKinfe,PotatoKnife { @Override public void cutTomato() { System.out.println("Chef Li is cutting tomatoes"); } @Override public void cutPotato() { System.out.println("Chef Li is cutting potatoes"); } } /*Suppose there is such a case scenario, now there is an interface knife, given that he has three capabilities, can cut apples, tomatoes, potatoes, Chef Zhang and Chef Li have these abilities respectively. There is a fruit shop class, assuming that Master Zhang is needed to cut apples and tomatoes, and another vegetable shop class needs Master Li is here to cut tomatoes and potatoes*/ //fruit shop class FruitShop { // Pass the interface type as a parameter public void cutApple(AppleKnife knife) { knife.cutApple(); } public void cutTomato(TomatoKinfe knife) { knife.cutTomato(); } } //Vegetable store class VegetableShop { public void cutTomato(TomatoKinfe knife) { knife.cutTomato(); } public void cutPotato(PotatoKnife knife) { knife.cutPotato(); } }
Summary
The principle of interface isolation is that when a class relies on (uses) another class through an interface, it is necessary to ensure that the interface it depends on is the smallest.
If there are methods in the interface that are not used, they are isolated, and the method of isolation is to split the original interface into the smallest granularity to avoid coupling
Three comparison with the single responsibility principle
Single responsibility principle: Reasonable responsibility decomposition, a class is only responsible for one responsibility
Interface Segregation Principle: Dependencies between classes should be established on the smallest interface
Same point
Both require the structure to be split, both require smaller granularity, and both want to reduce coupling
difference
different viewing angles
Single Responsibility Principle: classes and interfaces have a single responsibility, focusing on responsibility
Interface isolation principle: we are required to use multiple specialized interfaces as much as possible, focusing on interface design
When we use the interface isolation principle for interface splitting, we must follow the single responsibility principle