# 接口隔离原则(Interface Segregation Principle)

介绍:客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。

也就是说,当一个类需要实现某一个接口的时候,但是这个接口中有些方法对它来说并不需要去实现,就需要将这个大的接口划分为小的接口。

# ISP例子

如图所示:A类通过接口Name依赖B类,但是A类只是使用到接口的1,2,3方法;B类通过接口Name依赖B类,但是A类只是使用到接口的1,4,5方法.

Use
Use
Use
Use
«interface»Name+ operation1(): void+ operation2(): void+ operation3(): void+ operation4(): void+ operation5(): voidABDC
Viewer does not support full SVG 1.1

按照上图写一段示例代码

public class Main {
	public static void main(String[] args) {
		
	}
}
class A{
	public void depen1(Name n) {
		n.operation1();
	}
	public void depen2(Name n) {
		n.operation2();
	}
	public void depen3(Name n) {
		n.operation3();
	}
}
class B implements Name {
	@Override
	public void operation1() {
		System.out.println("B 实现了 operation1");
	}
	@Override
	public void operation2() {
		System.out.println("B 实现了 operation2");
	}
	@Override
	public void operation3() {
		System.out.println("B 实现了 operation3");
	}
	@Override
	public void operation4() {
		System.out.println("B 实现了 operation4");
	}
	@Override
	public void operation5() {
		System.out.println("B 实现了 operation5");
	}
	
}
class C{
	public void depend1(Name n) {
		n.operation1();
	}
	public void depend4(Name n) {
		n.operation4();
	}
	public void depend5(Name n) {
		n.operation5();
	}
}
class D implements Name {
	@Override
	public void operation1() {
		System.out.println("D 实现了 operation1");
	}
	@Override
	public void operation2() {
		System.out.println("D 实现了 operation2");
	}
	@Override
	public void operation3() {
		System.out.println("D 实现了 operation3");
	}
	@Override
	public void operation4() {
		System.out.println("D 实现了 operation4");
	}
	@Override
	public void operation5() {
		System.out.println("D 实现了 operation5");
	}
	
}
interface Name {
	public void operation1();
	public void operation2();
	public void operation3();
	public void operation4();
	public void operation5();
}

这样写是没有问题的,也符合当前的类图。A类依赖B类只使用接口的1,2,3方法,所以按道理说B类只需要实现1,2,3方法即可,同样,C类依赖B类也是这样的问题。多写了一段无用的代码,不需要实现的方法就应该撤掉,所以接口需要重新设计,使它们各自只实现自己需要的功能。

这个时候就需要将接口隔离,也就是拆分。

拆分后代码的类图

Use
Use
Use
Use
Use
Use
Use
Use
ACBD«interface»Name1+ operation1(): void«interface»Name3+ operation4(): void+ operation5(): void«interface»Name2+ operation2(): void+ operation3(): void
Viewer does not support full SVG 1.1

这个时候可以看到将接口拆分为三个,B类D类只需要按需实现就可以了,虽然增加了两个接口,但是确使代码结构变得清晰了起来,代码量也少了。

这个是实现的代码,结构确实清晰了不少。

public class Main {
	public static void main(String[] args) {
		
	}
}
class A{
	public void depen1(Name1 n) {
		n.operation1();
	}
	public void depen2(Name2 n) {
		n.operation2();
	}
	public void depen3(Name2 n) {
		n.operation3();
	}
}
class B implements Name1,Name2 {
	@Override
	public void operation1() {
		System.out.println("B 实现了 operation1");
	}
	@Override
	public void operation2() {
		System.out.println("B 实现了 operation2");
	}
	@Override
	public void operation3() {
		System.out.println("B 实现了 operation3");
	}
	
}
class C{
	public void depend1(Name1 n) {
		n.operation1();
	}
	public void depend4(Name3 n) {
		n.operation4();
	}
	public void depend5(Name3 n) {
		n.operation5();
	}
}
class D implements Name1,Name3 {
	@Override
	public void operation1() {
		System.out.println("D 实现了 operation1");
	}
	@Override
	public void operation4() {
		System.out.println("D 实现了 operation4");
	}
	@Override
	public void operation5() {
		System.out.println("D 实现了 operation5");
	}
	
}
interface Name1 {
	public void operation1();
}
interface Name2 {
	public void operation2();
	public void operation3();
}
interface Name3 {
	public void operation4();
	public void operation5();
}

发现自己以前写的代码的接口也要去隔离隔离了。