J
jn_betterfly
Unregistered / Unconfirmed
GUEST, unregistred user!
在建造者模式中,我们生成一个Product实际上是通过一个Director按照确定的步骤一步一步生成
的。如模式编程里的例子,生成一个DataSet,
function TfrmMain.BuildDataSet(aBuilder:TDBBuilder;aOwner:TWinControl): TDataSet;
begin
with aBuilderdo
begin
BuildConnection(aOwner);
BuildDataSet(aOwner);
result:=GetDataSet;
end;
end;
它是按照BuildConnection,然后再BuildDataSet,最后通过GetDataSet这三个确定的步骤完成的。根据
生成的具体的DataSet不同,BuildConnection和BuildDataSet的具体内容是不同的。
仔细考虑一下,这一点和模板模式有很大的相似之处,模板模式里抽象基类里的模板方法给我们规定了一个完成某个功能的骨干或框架,但在派生类中的具体实现时会根据实际情况在实现细节上会有不同。
所以,现在再考虑一下建造者模式,只要我们要创建的Product的创建过程是固定的,不会出现建造
步骤上的顺序的不同,那么我们完全可以把建造的过程用一个和模板模式中模板方法封装起来。这样建造的过程就不用Director来完成了,直接由模板方法来实现就可以了,或者说用模板方法把Director方法替换掉。
下面写一下主要代码:
type
TDBBuilder = class(TObject)
protected
FDataSet: TDataSet;
procedure BuildConnection(AOwner:TComponent);
virtual;
abstract;//将建造的过程方法设定protected,只能由模板方法调用
procedure BuildDataSet(AOwner:TComponent);
virtual;
abstract;
public
function GetDataSet(AOwner:TComponent): TDataSet;//由GetDataSet方法来代替Director方法,也就是模板方法
end;
TADOBuilder = class(TDBBuilder)
private
FADOConnection: TADOConnection;
protected
procedure BuildConnection(AOwner:TComponent);
override;
procedure BuildDataSet(AOwner:TComponent);
override;
end;
TBEDBuilder = class(TDBBuilder)
private
FDatabase: TDatabase;
protected
procedure BuildConnection(AOwner:TComponent);
override;
procedure BuildDataSet(AOwner:TComponent);
override;
end;
{
********************************** TDBBuilder **********************************
}
function TDBBuilder.GetDataSet(AOwner:TComponent): TDataSet;//由GetDataSet来封装建造的过程,也就是定义了模板方法的框架
begin
BuildConnection(AOwner);
BuildDataSet(AOwner);
Result:=FDataSet;
end;
这样在客户端就可以直接调用GetDataSet方法,而不用再在客户端定义Director方法,即TClient.BuildDataSet.
以生成Table为例,用建造者模式在客户端代码如下:
if RadioGroup1.Buttons[0].Checked then
begin
if (FBDEBuilder=nil) then
FBDEBuilder:=TBDEBuilder.create;
FDataSet:=BuildDataSet(FBDEBuilder,self);由BuildDataSet这个Director方法负责创建过程
DBGrid1.color:=clMoneyGreen;
end;
如果用模板模式的话,代码如下:
if RadioGroup1.Buttons[0].Checked then
begin
if (FBDEBuilder=nil) then
FBDEBuilder:=TBDEBuilder.create;
FDataSet:=FBDEBuilder.GetDataSet(self);//直接调用模板方法
DBGrid1.color:=clMoneyGreen;
end;
总结,建造者模式是一个创建型模式,目的是创建一个Product,而模板模式是一个行为模式,目的是提供解决同一问题的不同方法,二者的出发点是不同的,但是如果从算法的构造上看,建造者模式和模板模式有很大的相似之处。二者都是遵循一定的步骤来完成各自的操作的,这样如果建造模式中的建造过程是固定的,那我们完全可以利用模板模式把建造过程封装起来,这样我们就没有必要再去在客户端写Director方法,如果在客户端写Director方法的话就要求我们对建造过程相当熟悉,实际上加重了我们在客户端编码的工作,如果用模板方法实现的话,我们可以不必关心他的建造过程,直接调用模板方法即可,这样就可以简化我们的客户端程序。
当然,建造者模式复用的方式实际上是由Director实现的,也就是说我们可以定义不同的Director方法来使用建造者模式中的建造过程,这时,如果不同的Director方法调用建造过程方法的顺序不同,那我们就不能利用模板方法实现了,因为模板方法中的步骤必须是固定的。但是我现在还没有想起什么很好的具体例子来说明这个问题,也就是对于同一Product,它的建造过程顺序可以不同。
以上仅是我个人的一些观点和看法,不知道对不对,希望大家批评指正
上面的例子用模板方法已经实现,如果需要源码可以e_mail给我:zhaocheng28@163.com
的。如模式编程里的例子,生成一个DataSet,
function TfrmMain.BuildDataSet(aBuilder:TDBBuilder;aOwner:TWinControl): TDataSet;
begin
with aBuilderdo
begin
BuildConnection(aOwner);
BuildDataSet(aOwner);
result:=GetDataSet;
end;
end;
它是按照BuildConnection,然后再BuildDataSet,最后通过GetDataSet这三个确定的步骤完成的。根据
生成的具体的DataSet不同,BuildConnection和BuildDataSet的具体内容是不同的。
仔细考虑一下,这一点和模板模式有很大的相似之处,模板模式里抽象基类里的模板方法给我们规定了一个完成某个功能的骨干或框架,但在派生类中的具体实现时会根据实际情况在实现细节上会有不同。
所以,现在再考虑一下建造者模式,只要我们要创建的Product的创建过程是固定的,不会出现建造
步骤上的顺序的不同,那么我们完全可以把建造的过程用一个和模板模式中模板方法封装起来。这样建造的过程就不用Director来完成了,直接由模板方法来实现就可以了,或者说用模板方法把Director方法替换掉。
下面写一下主要代码:
type
TDBBuilder = class(TObject)
protected
FDataSet: TDataSet;
procedure BuildConnection(AOwner:TComponent);
virtual;
abstract;//将建造的过程方法设定protected,只能由模板方法调用
procedure BuildDataSet(AOwner:TComponent);
virtual;
abstract;
public
function GetDataSet(AOwner:TComponent): TDataSet;//由GetDataSet方法来代替Director方法,也就是模板方法
end;
TADOBuilder = class(TDBBuilder)
private
FADOConnection: TADOConnection;
protected
procedure BuildConnection(AOwner:TComponent);
override;
procedure BuildDataSet(AOwner:TComponent);
override;
end;
TBEDBuilder = class(TDBBuilder)
private
FDatabase: TDatabase;
protected
procedure BuildConnection(AOwner:TComponent);
override;
procedure BuildDataSet(AOwner:TComponent);
override;
end;
{
********************************** TDBBuilder **********************************
}
function TDBBuilder.GetDataSet(AOwner:TComponent): TDataSet;//由GetDataSet来封装建造的过程,也就是定义了模板方法的框架
begin
BuildConnection(AOwner);
BuildDataSet(AOwner);
Result:=FDataSet;
end;
这样在客户端就可以直接调用GetDataSet方法,而不用再在客户端定义Director方法,即TClient.BuildDataSet.
以生成Table为例,用建造者模式在客户端代码如下:
if RadioGroup1.Buttons[0].Checked then
begin
if (FBDEBuilder=nil) then
FBDEBuilder:=TBDEBuilder.create;
FDataSet:=BuildDataSet(FBDEBuilder,self);由BuildDataSet这个Director方法负责创建过程
DBGrid1.color:=clMoneyGreen;
end;
如果用模板模式的话,代码如下:
if RadioGroup1.Buttons[0].Checked then
begin
if (FBDEBuilder=nil) then
FBDEBuilder:=TBDEBuilder.create;
FDataSet:=FBDEBuilder.GetDataSet(self);//直接调用模板方法
DBGrid1.color:=clMoneyGreen;
end;
总结,建造者模式是一个创建型模式,目的是创建一个Product,而模板模式是一个行为模式,目的是提供解决同一问题的不同方法,二者的出发点是不同的,但是如果从算法的构造上看,建造者模式和模板模式有很大的相似之处。二者都是遵循一定的步骤来完成各自的操作的,这样如果建造模式中的建造过程是固定的,那我们完全可以利用模板模式把建造过程封装起来,这样我们就没有必要再去在客户端写Director方法,如果在客户端写Director方法的话就要求我们对建造过程相当熟悉,实际上加重了我们在客户端编码的工作,如果用模板方法实现的话,我们可以不必关心他的建造过程,直接调用模板方法即可,这样就可以简化我们的客户端程序。
当然,建造者模式复用的方式实际上是由Director实现的,也就是说我们可以定义不同的Director方法来使用建造者模式中的建造过程,这时,如果不同的Director方法调用建造过程方法的顺序不同,那我们就不能利用模板方法实现了,因为模板方法中的步骤必须是固定的。但是我现在还没有想起什么很好的具体例子来说明这个问题,也就是对于同一Product,它的建造过程顺序可以不同。
以上仅是我个人的一些观点和看法,不知道对不对,希望大家批评指正
上面的例子用模板方法已经实现,如果需要源码可以e_mail给我:zhaocheng28@163.com