《GOF设计模式》—生成器(Builder)—Delphi源码示例:生成器接口

示例:生成器接口

说明:

1)、定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2)、结构

 

生成器

Builder:抽象生成器,为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder:具体生成器,实现Builder的接口以构造和装配该产品的各个部件。定义并明确它所创建的表示。提供一个检索产品的接口来取得Product(例如,GetASCIITextGetTextWidget)。

导向器

Director:构造一个使用Builder接口的对象。

产品

Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

3)、协作

<1>、客户创建Director对象,并用它所想要的Builder对象进行配置。

<1>、一旦产品部件被生成,导向器就会通知生成器。

<3>、生成器处理导向器的请求,并将产品部件(如Text标记)添加到该产品中。

<4>、客户从生成器中检索产品(Text文档)。

 

特点:

通常情况下,一个抽象的Builder类为导向者可能要求创建的每一个构件定义一个操作,这些操作缺省情况下什么都不做。一个ConcreteBuilder类对它有兴趣创建的构件重定义这些操作。

客户不需要知道产品内部用到的类的信息,这些产品内部类是不会出现在Builder接口中的。

代码:

 

unit uBuilder;

 

interface

 

uses

    Classes;

 

type

    TPart = class

    private

        FState: string;

    public

        property State: string read FState write FState;

    end;

    TPartA = class(TPart)

    public

        constructor Create;

    end;

    TPartB = class(TPart)

    public

        constructor Create;

    end;

    TPartC = class(TPart)

    public

        constructor Create;

    end;

 

    TPartList = class

    private

        FItemList: TList;

        function GetCount: Integer;

        function GetItems(Index: integer): TPart;

    public

        constructor Create;

        destructor Destroy; override;

        //---

        procedure Clear;

        function Add(const Part: TPart): integer;

        //---

        property Count: Integer read GetCount;

        property Items[Index: integer]: TPart read GetItems;

    end;

 

    TProduct = class

    private

        FParts: TPartList;

        function GetState: string;

    public

        constructor Create;

        destructor Destroy; override;

        //---

        procedure AddPart(Part: TPart);

        //---

        property State: string read GetState;

    end;

 

    TBuilder = class

    public

        procedure BuildPartA; virtual;

        procedure BuildPartB; virtual;

        procedure BuildPartC; virtual;

    end;

    TConcreteBuilder = class(TBuilder)

    private

        FProduct: TProduct;

    public

        constructor Create;

        //---

        procedure BuildPartA; override;

        procedure BuildPartB; override;

        procedure BuildPartC; override;

        //---

        function GetResult: TProduct;

    end;

 

    TDirector = class

    private

        FBuilder: TBuilder;

    public

        constructor Create(Builder: TBuilder);

        //---

        procedure Construct;

    end;

 

implementation

 

constructor TPartA.Create;

begin

    self.State := 'PartA';

end;

 

constructor TPartB.Create;

begin

    self.State := 'PartB';

end;

 

constructor TPartC.Create;

begin

    self.State := 'PartC';

end;

 

constructor TPartList.Create;

begin

    inherited;

    //---

    FItemList := TList.Create;

end;

 

destructor TPartList.Destroy;

begin

    Clear;

    FItemList.Free;

    //---

    inherited;

end;

 

function TPartList.Add(const Part: TPart): integer;

begin

    if Assigned(Part) then

        Result := FItemList.Add(Part)

    else

        Result := -1;

end;

 

procedure TPartList.Clear;

var

    i: Integer;

begin

    with FItemList do

    begin

        for i := 0 to Count - 1 do

            TObject(Items[i]).Free;

        //---

        Clear;

    end;

end;

 

function TPartList.GetCount: Integer;

begin

    Result := FItemList.Count;

end;

 

function TPartList.GetItems(Index: integer): TPart;

begin

    Result := FItemList[Index];

end;

 

constructor TProduct.Create;

begin

    FParts := TPartList.Create;

end;

 

destructor TProduct.Destroy;

begin

    FParts.Free;

    //---

    inherited;

end;

 

procedure TProduct.AddPart(Part: TPart);

begin

    FParts.Add(Part);

end;

 

function TProduct.GetState: string;

var

    i: integer;

begin

    Result := '';

    //---

    with FParts do

    begin

        for i := 0 to Count - 1 do

            Result := Result + Items[i].State + ' ';

    end;

end;

 

procedure TBuilder.BuildPartA;

begin

 

end;

 

procedure TBuilder.BuildPartB;

begin

 

end;

 

procedure TBuilder.BuildPartC;

begin

 

end;

 

constructor TConcreteBuilder.Create;

begin

    FProduct := nil;

end;

 

procedure TConcreteBuilder.BuildPartA;

begin

    if FProduct = nil then

        FProduct := TProduct.Create;

    //---

    FProduct.AddPart(TPartA.Create);

end;

 

procedure TConcreteBuilder.BuildPartB;

begin

    if FProduct = nil then

        FProduct := TProduct.Create;

    //---

    FProduct.AddPart(TPartB.Create);

end;

 

procedure TConcreteBuilder.BuildPartC;

begin

    if FProduct = nil then

        FProduct := TProduct.Create;

    //---

    FProduct.AddPart(TPartC.Create);

end;

 

function TConcreteBuilder.GetResult: TProduct;

begin

    Result := FProduct;

end;

 

constructor TDirector.Create(Builder: TBuilder);

begin

    FBuilder := Builder;

end;

 

procedure TDirector.Construct;

begin

    with FBuilder do

    begin

        BuildPartA;

        BuildPartB;

        BuildPartC;

    end;

end;

 

end.

 

procedure TForm1.Button1Click(Sender: TObject);

var

    AClass: TClass;

    Builder: TConcreteBuilder;

    Director: TDirector;

    Product: TProduct;

begin

    Builder := TConcreteBuilder.Create;

    Director := TDirector.Create(Builder);

    //--

    Director.Construct;

    Product := Builder.GetResult;

    showmessage(Product.State);

    //---

    Product.Free;

    Builder.Free;

    Director.Free;

end;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值