首页 Flutter 设计模式建造者模式
文章
取消

Flutter 设计模式建造者模式

建造者模式定义

造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

建造者模式由来

无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如计算机,它包括CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等不见组件而成的。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一台完成的计算机,可以通过建造者模式对其进行设计与描述,建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。

建造者模式结构

Builder:抽象建造者

它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。

ConcreteBuilder:具体建造者

实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。

Director:指挥者

它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

Product:产品角色

它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。

建造者模式案例

我们已组件电脑的过程用建造者模式实现

1、产品角色(电脑)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 产品角色
class Computer {

  // 电脑cpu
  String cpu;
  // 电脑内存
  String memory;
  // 电脑主板
  String mainBoard;
  // 电脑屏幕
  String screen;
  // 更多属性,不一一举例
  // ...

  Computer(this.cpu, this.memory, this.mainBoard, this.screen);
  
}

2、抽象建造者(创建产品抽象接口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 抽象建造者
abstract class Builder {

  Computer computer = Computer("", "", "", "",);

  void buildCpu();

  void buildMemory();

  void buildMainBoard();

  void buildScreen();

  Computer getResult() {
    return computer;
  }

}

3、具体建造者(具体建造各部件过程)

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
// 具体建造者
class ConcreteBuilder extends Builder {
  @override
  void buildCpu() {
    computer.cpu = "AMD的CPU";
  }

  @override
  void buildMainBoard() {
    computer.mainBoard = "华硕主板";
  }

  @override
  void buildMemory() {
    computer.memory = "金士顿64G内存";
  }

  @override
  void buildScreen() {
    computer.screen = "AOC 4k屏";
  }
}

// 具体建造者2
class Concrete2Builder extends Builder {
   @override
  void buildCpu() {
    computer.cpu = "Intel CPU";
  }

  @override
  void buildMainBoard() {
    computer.mainBoard = "华硕主板";
  }

  @override
  void buildMemory() {
    computer.memory = "联想64G内存";
  }

  @override
  void buildScreen() {
    computer.screen = "三星 4k";
  }
}

4、指挥者(组装电脑)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 指挥者
class ComputerDirector {
  
  // 抽象建造者对象
  Builder builder;

  ComputerDirector(this.builder);
  
  // 组装各部电脑零件
  Computer constructor() {
    // 组装CPU
    builder.buildCpu();
    // 组装内存
    builder.buildMemory();
    // 组装主板
    builder.buildMainBoard();
    // 组装屏幕
    builder.buildScreen();
    return builder.getResult();
  }
}

5、使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void main(List<String> args) {

  // 具体构造者(电脑每个部件的创建方法)
  Builder builder = ConcreteBuilder();
  // 指挥者(电脑复杂的组装过程)
  ComputerDirector computerDirector = ComputerDirector(builder);
  // 具体产品(电脑)
  Computer computer = computerDirector.constructor();
  print(computer.cpu);
  print(computer.memory);
  print(computer.mainBoard);
  print(computer.screen);

  // 具体构造者(电脑每个部件的创建方法)
  Builder builder2 = Concrete2Builder();
  // 指挥者(电脑复杂的组装过程)
  ComputerDirector computerDirector2 = ComputerDirector(builder2);
  // 具体产品(电脑)
  Computer computer2 = computerDirector2.constructor();
  print(computer2.cpu);
  print(computer2.memory);
  print(computer2.mainBoard);
  print(computer.screen);
}

6、运行结果

1
2
3
4
5
6
7
8
9
10
Connecting to VM Service at http://127.0.0.1:65212/CazqtRJBmtw=/
AMDCPU
金士顿64G内存
华硕主板
AOC 4k
Intel CPU
联想64G内存
华硕主板
AOC 4k
Exited

7、完整代码

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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
void main(List<String> args) {
  // 具体构造者(电脑每个部件的创建方法)
  Builder builder = ConcreteBuilder();
  // 指挥者(电脑复杂的组装过程)
  ComputerDirector computerDirector = ComputerDirector(builder);
  // 具体产品(电脑)
  Computer computer = computerDirector.constructor();
  print(computer.cpu);
  print(computer.memory);
  print(computer.mainBoard);
  print(computer.screen);

  // 具体构造者(电脑每个部件的创建方法)
  Builder builder2 = Concrete2Builder();
  // 指挥者(电脑复杂的组装过程)
  ComputerDirector computerDirector2 = ComputerDirector(builder2);
  // 具体产品(电脑)
  Computer computer2 = computerDirector2.constructor();
  print(computer2.cpu);
  print(computer2.memory);
  print(computer2.mainBoard);
  print(computer.screen);
}

// 产品角色
class Computer {
  // 电脑cpu
  String cpu;
  // 电脑内存
  String memory;
  // 电脑主板
  String mainBoard;
  // 电脑屏幕
  String screen;
  // 更多属性,不一一举例
  // ...

  Computer(this.cpu, this.memory, this.mainBoard, this.screen);
}

// 抽象建造者
abstract class Builder {
  Computer computer = Computer(
    "",
    "",
    "",
    "",
  );

  void buildCpu();

  void buildMemory();

  void buildMainBoard();

  void buildScreen();

  Computer getResult() {
    return computer;
  }
}

// 具体建造者
class ConcreteBuilder extends Builder {
  @override
  void buildCpu() {
    computer.cpu = "AMD的CPU";
  }

  @override
  void buildMainBoard() {
    computer.mainBoard = "华硕主板";
  }

  @override
  void buildMemory() {
    computer.memory = "金士顿64G内存";
  }

  @override
  void buildScreen() {
    computer.screen = "AOC 4k屏";
  }
}

// 具体建造者2
class Concrete2Builder extends Builder {
  @override
  void buildCpu() {
    computer.cpu = "Intel CPU";
  }

  @override
  void buildMainBoard() {
    computer.mainBoard = "华硕主板";
  }

  @override
  void buildMemory() {
    computer.memory = "联想64G内存";
  }

  @override
  void buildScreen() {
    computer.screen = "三星 4k";
  }
}

// 指挥者
class ComputerDirector {
  // 抽象建造者对象
  Builder builder;

  ComputerDirector(this.builder);

  // 组装各部电脑零件
  Computer constructor() {
    // 组装CPU
    builder.buildCpu();
    // 组装内存
    builder.buildMemory();
    // 组装主板
    builder.buildMainBoard();
    // 组装屏幕
    builder.buildScreen();
    return builder.getResult();
  }
}

8、分析

我们通过构造者模式对电脑的案例进行了组装,客户端完全不需要产品内部组成细节,对产品本身和产品的创建过程进行了解耦。而且新增具体建造者也无需修改原有类库的代码,系统扩展方便。

总结

优点

  • 更加精细的控制产品的创建过程
  • 封装性好,构建和表示分离。
  • 扩展性好,增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程。
  • 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

缺点

  • 产品的组成部分必须相同,限制了使用范围
  • 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
本文由作者按照 CC BY 4.0 进行授权

Flutter 设计模式原型模式

-