什么是接口隔离原则?
接口隔离原则(Interface Segregation Principle)指的是对高层接口的独立、分化,客户端对类的依赖基于最小接口,而不依赖不需要的接口。
接口隔离原则有什么作用?
- 将臃肿的接口颗粒化,提高系统的灵活性和可维护性
- 接口隔离提高系统内聚性、降低耦合性
- 合理的接口颗粒化,保证系统的稳定性
- 无需防止许多不用的方法,减少工程代码冗余
案例分析
以动物类的接口举例,猫可以进食、游泳、小鸟可以飞
1、首先需要定义动物类接口,并增加进食、游泳、飞的方法
2、定义猫类,实现动物类接口
3、定义小鸟类,实现动物类接口
方案一:初始设计
1、定义动物接口类
1
2
3
4
5
6
7
8
| abstract class IAnimal {
// 进食
void eat();
// 游泳
void swim();
// 飞
void fly();
}
|
2、小鸟实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| class Brid implements IAnimal {
@override
void eat() {
print("小鸟进食");
}
@override
void fly() {
print("小鸟飞");
}
@override
void swim() {
print('小鸟游泳');
}
}
|
3、猫实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| class Cat implements IAnimal {
@override
void eat() {
print("猫进食");
}
@override
void fly() {
print("猫飞");
}
@override
void swim() {
print('猫游泳');
}
}
|
4、使用
1
2
3
4
5
6
7
8
9
10
11
12
13
| void main(List<String> args) {
Brid brid = Brid();
brid.eat();
brid.fly();
brid.swim();
Cat cat = Cat();
cat.eat();
cat.fly();
cat.swim();
}
|
5、运行结果
1
2
3
4
5
6
7
8
| Connecting to VM Service at http://127.0.0.1:54490/cTwb35EwvzM=/
小鸟进食
小鸟飞
小鸟游泳
猫进食
猫飞
猫游泳
Exited
|
6、完整代码
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
| void main(List<String> args) {
Brid brid = Brid();
brid.eat();
brid.fly();
brid.swim();
Cat cat = Cat();
cat.eat();
cat.fly();
cat.swim();
}
abstract class IAnimal {
// 进食
void eat();
// 游泳
void swim();
// 飞
void fly();
}
class Brid implements IAnimal {
@override
void eat() {
print("小鸟进食");
}
@override
void fly() {
print("小鸟飞");
}
@override
void swim() {
print('小鸟游泳');
}
}
class Cat implements IAnimal {
@override
void eat() {
print("猫进食");
}
@override
void fly() {
print("猫飞");
}
@override
void swim() {
print('猫游泳');
}
}
|
7、分析
在上面代码运行后我们看出小鸟居然可以游泳,而且猫可以飞,这很显然是不可能的,所以这里就违背了接口隔离原则,我们来看下如果优化
方案二:接口隔离
我们用接口隔离原则去根据动物行为的不同设计不同的接口
1、定义进食接口类
1
2
3
| abstract class IEatAnimal {
void eat();
}
|
2、定义飞接口类
1
2
3
| abstract class IFlyAnimal {
void fly();
}
|
3、定义游泳接口类
1
2
3
| abstract class ISwimAnimal {
void swim();
}
|
4、定义猫实现类
1
2
3
4
5
6
7
8
9
10
11
12
| class Cat implements ISwimAnimal,IEatAnimal {
@override
void eat() {
print("猫进食");
}
@override
void swim() {
print("猫游泳");
}
}
|
5、定义小鸟实现类
1
2
3
4
5
6
7
8
9
10
11
12
| class Brid implements IFlyAnimal,IEatAnimal {
@override
void fly() {
print("小鸟飞");
}
@override
void eat() {
print("小鸟进食");
}
}
|
6、运行
1
2
3
4
5
6
7
8
9
10
11
| void main(List<String> args) {
Brid brid = Brid();
brid.fly();
brid.eat();
Cat cat = Cat();
cat.eat();
cat.swim();
}
|
7、运行结果
1
2
3
4
5
6
| Connecting to VM Service at http://127.0.0.1:55204/V0sMta-EEs4=/
小鸟飞
小鸟进食
猫进食
猫游泳
Exited
|
8、完整代码
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
| void main(List<String> args) {
Brid brid = Brid();
brid.fly();
brid.eat();
Cat cat = Cat();
cat.eat();
cat.swim();
}
abstract class IFlyAnimal {
void fly();
}
abstract class IEatAnimal {
void eat();
}
abstract class ISwimAnimal {
void swim();
}
class Cat implements ISwimAnimal,IEatAnimal {
@override
void eat() {
print("猫进食");
}
@override
void swim() {
print("猫游泳");
}
}
class Brid implements IFlyAnimal,IEatAnimal {
@override
void fly() {
print("小鸟飞");
}
@override
void eat() {
print("小鸟进食");
}
}
|
9、分析
我们通过遵守接口隔离原则去根据动物行为的不同设计不同的接口,这样当动物不管有什么行为或者属性直接实现对应的接口类即可。
总结
虽然接口隔离原则能对接口颗粒化,能很好的避免过度臃肿的接口设计,但如果接口粒度太小就会导致接口数据剧增,代码可读性就会变差,所以根据实际业务尽可能遵守接口隔离原则去设计。