接口隔离原则,全称Interface Segregation Principle,英文缩写ISP。
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
满足接口隔离原则的前提就是接口设计得不应该过于庞大。举个例子,现在设计一个动物animal接口,动物应该都会跑步的。
public interface IAnimal { //动物跑步 void Run(); }
然后现在有狗和猫使用接口,也实现了run方法,设计看起来没有问题。
public class Dog : IAnimal { public void Run() { Console.WriteLine("dog run"); } } public class Cat : IAnimal { public void Run() { Console.WriteLine("cat run"); } }
后面就加入了新的鹰eagle类,鹰是可以飞的,所以在animal接口上添加fly方法,让鹰可以实现fly的方法。
public interface IAnimal { //动物跑步 void Run(); //动物飞 void Fly(); } public class Eagle : IAnimal { public void Fly() { Console.WriteLine("eagle fly"); } //对于鹰是无用接口 public void Run() { throw new NotImplementedException(); } }
由于修改了animal接口,所以之前的类也需要进行修改。
public class Dog : IAnimal { public void Run() { Console.WriteLine("dog run"); } //对于狗是无用接口 public void Fly() { throw new NotImplementedException(); } } public class Cat : IAnimal { public void Run() { Console.WriteLine("cat run"); } //对于猫是无用接口 public void Fly() { throw new NotImplementedException(); } }
那么问题了,这里只新增了鹰,只需要实现fly的方法就可以的,但由于在animal接口上进行了修改,dog和cat类也要进行相应的变更,去实现一个无效的接口方法。由于每一个实现类都依赖了它们不需要的接口,使得层与层之间的耦合度增加,导致了不需要的接口修改时,实现类也不得不跟着修改。
根据接口隔离原则,对上面的设计进行修改,将动物animal设计成两个接口。
//哺乳动物 public interface Mammal { void Run(); } //鸟类 public interface Bird { void Fly(); }
然后不同的类去实现不同的接口。
public class Dog : Mammal { public void Run() { Console.WriteLine("dog run"); } } public class Cat : Mammal { public void Run() { Console.WriteLine("cat run"); } } public class Eagle : Bird { public void Fly() { Console.WriteLine("eagle fly"); } }
这样,不同的类就只需要实现自己所需要的方法,如果要新增其它动物,只需要在对应的接口和实现类上进行修改就行。这样设计,降低了接口的耦合度,可以看出接口隔离原则的必要性。