对于这样的有多个零件组成的复杂产品的组装过程,就可以使用Builder建造者模式来完成。
建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
我们来看看其UML模型:
建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法如BuliderCPU,BuilderBoard等,另一个是结果返还方法GetComputer。
具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例,这里为DellBuilder类,IBMBuilder类。这个角色主要完成实现Builder角色提供的接口,一步一步完成创建产品实例的过程。
指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象,这里为ComputerDirector类。
using System;2
using System.Collections;3

4

5
namespace BuilderPattom6
{7
/// <summary>8
///============== Program Description==============9
///Name:BuilderPattom.cs10
///Objective:BuilderPattom 11
///Date:2006-04-2812
///Written By coffee.liu13
///================================================14
/// </summary>15
class Class116
{17
/// <summary>18
/// 应用程序的主入口点。19
/// </summary>20
[STAThread]21
static void Main(string[] args)22
{23
Hashtable PH;24
ComputerDirector CD=new ComputerDirector();25
Builder B1=new DellBuilder();26
Builder B2=new IBMBuilder();27
CD.Create(B1);28
PH=(B1.GetComputer()) as Hashtable;29
Console.WriteLine("Dell Computers
..");30
Console.WriteLine("Board:"+Convert.ToString(PH["Board"]));31
Console.WriteLine("CPU:"+Convert.ToString(PH["CPU"]));32
Console.WriteLine("Menory:"+Convert.ToString(PH["Menory"]));33
CD.Create(B2);34
PH=(B2.GetComputer()) as Hashtable;35
Console.WriteLine("IBM Computers
..");36
Console.WriteLine("Board:"+Convert.ToString(PH["Board"]));37
Console.WriteLine("CPU:"+Convert.ToString(PH["CPU"]));38
Console.WriteLine("Menory:"+Convert.ToString(PH["Menory"]));39

40
}41
}42
//abstractBuilder43
abstract class Builder{44
abstract public Hashtable Createhash();45
abstract public void BuilderCpu();46
abstract public void BuilderBoard();47
abstract public void BuilderMenory();48
abstract public Object GetComputer();49
}50
class DellBuilder:Builder{51
private Hashtable myHashTable;52
public override Hashtable Createhash()53
{54
return myHashTable=new Hashtable();55
}56

57
override public void BuilderCpu()58
{59
myHashTable.Add("CPU","Intel");60
}61
public override void BuilderBoard()62
{63
myHashTable.Add("Board","DellBoard");64
}65
public override void BuilderMenory()66
{67
myHashTable.Add("Menory","DellMenory");68
}69
public override Object GetComputer()70
{71
return myHashTable;72
}73
}74
class IBMBuilder:Builder75
{76
private Hashtable myHashTable;77
public override Hashtable Createhash()78
{79
return myHashTable=new Hashtable();80
}81

82
override public void BuilderCpu()83
{84
myHashTable.Add("CPU","Intel");85
}86
public override void BuilderBoard()87
{88
myHashTable.Add("Board","IBMBoard");89
}90
public override void BuilderMenory()91
{92
myHashTable.Add("Menory","IBMMenory");93
}94
public override Object GetComputer()95
{96
return myHashTable;97
}98
}99
//Director100
class ComputerDirector{101
public void Create(Builder ABuilder){102
ABuilder.Createhash();103
ABuilder.BuilderBoard();104
ABuilder.BuilderCpu();105
ABuilder.BuilderMenory();106
}107
}108
}109

program BuilderPattom;2
//============== Program Description==============3
//Name:BuilderPattom.dpr4
//Objective:BuilderPattom5
//Date:2006-04-296
//Written By coffee.liu7
//================================================8
{$APPTYPE CONSOLE}9

10
uses11
SysUtils,Classes;12
//零件13
type Part=record14
Name:string;15
Valual:string;16
end;17
PPart=^Part;18
//具体产品19
type Product=class20
private21
AProduct:TList;22
public 23
constructor Create;24
procedure Add(APart:PPart);25
procedure Say();26
destructor Destroy();override;27
end;28
//建造者29
type Builder=class30
procedure BuilderCpu();virtual;abstract;31
procedure BuilderBoard();virtual;abstract;32
procedure BuilderMenory();virtual;abstract;33
function GetComputer:Tobject;virtual;abstract;34
end;35
//具体建造者36
type DellBuilder=class(Builder)37
private AProduct:Product;38
public39
procedure BuilderCpu();override;40
procedure BuilderBoard();override;41
procedure BuilderMenory();override;42
function GetComputer:Tobject;override;43
constructor Create();44
destructor Destroy();override;45

46
end;47
//具体建造者48
type IBMBuilder=class(Builder)49
private AProduct:Product;50
public51
procedure BuilderCpu();override;52
procedure BuilderBoard();override;53
procedure BuilderMenory();override;54
function GetComputer:Tobject;override;55
constructor Create();56
destructor Destroy();override;57
end;58
//指导者59
type ComputerDirector=class60
constructor Create(ABuilder:Builder);61
end;62

63

64
{ DellBuilder }65

66
procedure DellBuilder.BuilderBoard;67
var68
Pa:PPart;69
begin70
inherited;71
new(Pa); //创建指针,以下同72
Pa^.Name:='DELL';73
Pa^.Valual:='Board';74
AProduct.Add(pa);75
end;76

77
procedure DellBuilder.BuilderCpu;78
var79
Pa:PPart;80
begin81
inherited;82
new(Pa);83
Pa^.Name:='DELL';84
Pa^.Valual:='Cpu';85
AProduct.Add(pa);86
end;87

88
procedure DellBuilder.BuilderMenory;89
var90
Pa:PPart;91
begin92
inherited;93
new(Pa);94
Pa^.Name:='DELL';95
Pa^.Valual:='Menory';96
AProduct.Add(pa);97
end;98

99
constructor DellBuilder.Create;100
begin101
AProduct:=Product.Create;102
end;103

104
destructor DellBuilder.Destroy;105
begin106
AProduct.Free;107
inherited Destroy;108
end;109

110
function DellBuilder.GetComputer: Tobject;111
begin112
result:=AProduct;113
end;114

115
{ IBMBuilder }116

117
procedure IBMBuilder.BuilderBoard;118
var119
Pa:PPart;120
begin121
inherited;122
new(Pa);123
Pa^.Name:='IBM';124
Pa^.Valual:='Board';125
AProduct.Add(pa);126
end;127

128
procedure IBMBuilder.BuilderCpu;129
var130
Pa:PPart;131
begin132
inherited;133
new(Pa);134
Pa^.Name:='IBM';135
Pa^.Valual:='Cpu';136
AProduct.Add(pa);137
end;138

139
procedure IBMBuilder.BuilderMenory;140
var141
Pa:PPart;142
begin143
inherited;144
new(Pa);145
Pa^.Name:='IBM';146
Pa^.Valual:='Menory';147
AProduct.Add(pa);148
end;149

150
constructor IBMBuilder.Create;151
begin152
AProduct:=Product.Create;153
end;154

155
destructor IBMBuilder.Destroy;156
begin157
AProduct.Free;158
inherited Destroy;159
end;160

161
function IBMBuilder.GetComputer: Tobject;162
begin163
result:=AProduct;164
end;165

166
{ ComputerDirector }167

168
constructor ComputerDirector.Create(ABuilder: Builder);169
begin170
ABuilder.BuilderBoard();171
ABuilder.BuilderCpu();172
ABuilder.BuilderMenory()173
end;174

175
{ Product }176

177
procedure Product.Add(APart: PPart);178
begin179
AProduct.Add(APart);180
end;181

182
constructor Product.Create;183
begin184
AProduct:=TList.Create;185
end;186

187
destructor Product.Destroy;188
begin189

190
AProduct.Free;191
inherited Destroy;192
end;193

194
procedure Product.Say;195
var196
i:integer;197
begin198
for i:=0 to AProduct.Count-1 do199
begin200
Writeln(string(PPart(AProduct.Items[i])^.Name)+':'+PPart(AProduct.Items[i])^.Valual);201
Dispose(PPart(AProduct.Items[i]));//释放指针202
end;203

204
end;205
var206
ABuilder,BBuilder:Builder;207
DELLProduct,IBMProduct:Product;208
begin209
try210
ABuilder:=DellBuilder.Create;211
ComputerDirector.Create(ABuilder);212
DELLProduct:=Product(ABuilder.GetComputer);213
DELLProduct.Say;214
BBuilder:=IBMBuilder.Create;215
ComputerDirector.Create(BBuilder);216
IBMProduct:=Product(BBuilder.GetComputer);217
IBMProduct.Say;218
finally219
DELLProduct.Free;220
IBMProduct.Free;221
end;222
end.对于Pascal语言来说要特别注意对象的释放,因为作为Pascal可没有垃圾回收机制,我们应用了TList对象,这个对象是不会自动释放自己的。而且我们使用了指针,这也要进行释放。仔细看看程序的Destroy的运行流程,就会明白。
使用Builder模式的好处,可以让产品的组装过程同具体零件的生产分离开来,便于今后组成流程的独立演化,同时对于用户来说,他不需要知道具体的零件生产细节,他只要关心最终获得的产品就可以了。
在什么情况下需要使用建造者呢
1、 需要生成的产品对象有复杂的内部结构。
2、 需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
3、 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
建造者模式的效果:
1.生成器语序读者改变产品的内部表示,同时也隐藏呢产品如何组装的细节。
2.每个特定的生成器独立于其他的生成器,同时独立于程序的其他部分,这一点提高了对象的模块性,并使添加其他的生成器变得相对简单。
3.由于每个生成器是根据数据一步一步构建最终结果,所以能精确地控制生成器构建的每个结果。
生成器模式有点类似于抽象工厂模式,两者都返回由许多方法和对象组成的类,他们之间的主要差别是,抽象工厂返回的是一系列相关的类,而生成器是根据提供给它的数据一步一步地构建一个复杂的对象。

浙公网安备 33010602011771号