首页 Flutter 设计模式之接口隔离原则
文章
取消

Flutter 设计模式之接口隔离原则

什么是接口隔离原则?

接口隔离原则(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、分析

我们通过遵守接口隔离原则去根据动物行为的不同设计不同的接口,这样当动物不管有什么行为或者属性直接实现对应的接口类即可。

总结

虽然接口隔离原则能对接口颗粒化,能很好的避免过度臃肿的接口设计,但如果接口粒度太小就会导致接口数据剧增,代码可读性就会变差,所以根据实际业务尽可能遵守接口隔离原则去设计。

本文由作者按照 CC BY 4.0 进行授权

Flutter 设计模式之依赖倒置原则

Flutter 设计模式之里氏替换原则