接口隔离原则

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

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

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

# ISP例子

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

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

按照上图写一段示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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类也是这样的问题。多写了一段无用的代码,不需要实现的方法就应该撤掉,所以接口需要重新设计,使它们各自只实现自己需要的功能。

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

拆分后代码的类图

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

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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();
}

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