设计模式<创建型> | 生成器模式

生成器模式(Builder pattern)

将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。解决构造函数过多或者过于复杂。可以把构造函数里面的约束条件的校验使用建造者模式放到 builder 类中去。

结构图:

角色:

  1. 产品(Product):需要创建的产品,是最终生成的对象。
  2. 抽象生成器(IBuilder):声明产品构造步骤接口。
  3. 具体生成器(Concrete Builders):提供构造过程的不同实现。 具体生成器也可以构造不遵循通用接口的产品。
  4. 主管(Director): 调用端和创建者的中间人,负责执行自定义构造步骤。

适用场景:

  1. 需要构建同一产品的不同形态时。

优点:

  1. 可以将产品的创建分步执行。
  2. 可以生成不同形式的产品
  3. 将那些复杂的构造函数分离到(Builder)中。

缺点:

  1. 如果产品的形态过多将会有很多(Concrete Builders),导致复杂度上升。

代码(C#)

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
130
131
132
133
134

/// <summary>
/// 产品
/// </summary>
public class Phone
{
public string Cpu { get; set; }
public string Memory { get; set; }
public string Screen { get; set; }
}

/// <summary>
/// 抽象生成器
/// </summary>
public interface IPhoneBuilder
{
void BuildCpu();
void BuildMemory();
void BuildScreen();
}

/// <summary>
/// 具体生成器
/// </summary>
public class ApplePhoneBuilder : IPhoneBuilder
{
private Phone _phone = new Phone();

public void Reset()
{
_phone = new Phone();
}

public ApplePhoneBuilder()
{
Reset();
}

public void BuildCpu()
{
_phone.Cpu = "A16";
}

public void BuildMemory()
{
_phone.Memory = "4G";
}

public void BuildScreen()
{
_phone.Screen = "三星屏幕";
}

/// <summary>
/// 获取 Builder 好的产品
/// </summary>
/// <returns></returns>
public Phone GetProduct()
{
var result = _phone;
Reset();
return result;
}
}

/// <summary>
/// 具体生成器
/// </summary>
public class MiPhoneBuilder : IPhoneBuilder
{
private Phone _phone = new Phone();

public void Reset()
{
_phone = new Phone();
}

public MiPhoneBuilder()
{
Reset();
}

public void BuildCpu()
{
_phone.Cpu = "骁龙 8 gen2";
}

public void BuildMemory()
{
_phone.Memory = "16 G";
}

public void BuildScreen()
{
_phone.Screen = "京东方屏幕";
}

public Phone GetProduct()
{
var result = _phone;
Reset();
return result;
}
}

/// <summary>
/// 主管责执行构建步骤
/// </summary>
public class Director
{
private IPhoneBuilder _builder;

public Director(IPhoneBuilder builder)
{
_builder = builder;
}

public void ChangeBuilder(IPhoneBuilder builder) => _builder = builder;

public void Make()
{
_builder.BuildCpu();
_builder.BuildMemory();
_builder.BuildScreen();
}
}

// 使用
var applebuilder = new ApplePhoneBuilder();
// 生成器对象与主管类关联
var director = new Director(applebuilder);
director.Make();
var apple = applebuilder.GetProduct();

最后

生成器看起和工厂模式有点类似,但是它们是针对的场景是不同的,工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。建造者模式是用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”地创建不同的对象。

不建议 Director 直接返回产品,因为不同类型的生成器可能会创建不遵循相同接口的、完全不同的产品。所以生成器需要自行提供获取结果的方法。


设计模式<创建型> | 生成器模式
http://example.com/posts/29711.html
作者
她微笑的脸y
发布于
2023年2月23日
许可协议