《GOF设计模式》—组合(COMPOSITE)—Delphi源码示例:设备

示例:设备

说明:

计算机和立体声组合音响这样的设备经常被组装成“部分-整体层次结构”或者是“容器层次结构”。例如,机柜包括底盘、总线,底盘可包含驱动装置和平面板,总线含有多个插件等。这种结构可以很自然地用Composite模式进行模拟。

Equipment类为在“部分-整体层次结构”中的所有设备定义了一个接口。

Equipment声明一些操作返回一个设备的属性,例如它的能量消耗和价格。子类为指定的设备实现这些操作,Equipment还声明了一个CreateIterator操作,该操作为访问它的零件返回一个Iterator。这个操作的缺省实现返回一个NullIterator,它在空集上叠代。

Equipment的子类包括表示磁盘驱动器、集成电路和开关的Leaf类。CompositeEquipment是包含其他设备的基类,它也是Equipment的子类。

CompositeEquipment为访问和管理子设备定义了一些操作。操作AddRemove从存储在FEquipments成员变量中的设备列表中插入并删除设备。操作CreateIterator返回一个迭代器(ListIterator的一个实例)遍历这个列表。NetPrice的缺省实现使用CreateIterator来累加子设备的实际价格。

现在我们将计算机的底盘表示为CompositeEquipment的子类ChassisChassisCompositeEquipment继承了与子类有关的那些操作。

我们可用相似的方式定义其他设备容器,如CabinetBus。这样我们就得到了组装一台(非常简单)个人计算机所需的所有设备。

代码:

 

unit uIterator;

 

interface

 

uses classes;

 

type

    {迭代器}

    TIterator = class

    public

        procedure First; virtual; abstract;

        procedure Next; virtual; abstract;

        function IsDone: Boolean; virtual; abstract;

        function CurrentItem(): TObject; virtual; abstract;

    end;

    TListIterator = class(TIterator)

    private

        FList: TList;

        FIndex: Integer;

    public

        constructor Create(const AList: TList);

        //---

        procedure First; override;

        procedure Next; override;

        function IsDone: Boolean; override;

        function CurrentItem(): TObject; override;

    end;

 

implementation

 

constructor TListIterator.Create(const AList: TList);

begin

    inherited Create;

    //---

    FList := AList;

    FIndex := 0;

end;

 

procedure TListIterator.First();

begin

    FIndex := 0;

end;

 

procedure TListIterator.Next();

begin

    FIndex := FIndex + 1;

end;

 

function TListIterator.IsDone: Boolean;

begin

Result := FIndex >= FList.Count;

end;

 

function TListIterator.CurrentItem(): TObject;

begin

    Result := FList[FIndex];

end;

 

end.

 

unit uEquipment;

 

interface

 

uses

    SysUtils,Dialogs,Contnrs,uIterator;

 

type

    {设备接口}

    TEquipment = class

    private

        FName: String;

    public

        constructor Create(const AName: string);

        //---

        {用电量}

        function Power(): Integer; virtual; abstract;

        {设备价格}

        function NetPrice(): Currency; virtual; abstract;

        {设备折扣价}

        function DiscountPrice(): Currency; virtual; abstract;

        //---

        procedure Add(const AEquipment: TEquipment); virtual;

        procedure Remove(const AEquipment: TEquipment); virtual;

        function CreateIterator(): TIterator; virtual;

        //---

        property Name: String read FName write FName;

    end;

    {组合设备}

    TCompositeEquipment = class(TEquipment)

    private

        FEquipments: TObjectList;

    public

        constructor Create(const AName: string);

        destructor Destroy; override;

        //---

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

        //---

        procedure Add(const AEquipment: TEquipment);override;

        procedure Remove(const AEquipment: TEquipment);override;

        function CreateIterator: TIterator;override;

    end;

    {机柜}

    TCabinet = class(TCompositeEquipment)

    public

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

    end;

    {底盘}

    TChassis = class(TCompositeEquipment)

    public

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

    end;

    {总线}

    TBus = class(TCompositeEquipment)

    public

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

    end;

    {软驱}

    TFloppyDisk = class(TEquipment)

    public

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

    end;

    {插件}

    TCard = class(TEquipment)

    public

        function Power(): Integer; override;

        function NetPrice(): Currency; override;

        function DiscountPrice(): Currency; override;

    end;

 

implementation

 

constructor TEquipment.Create(const AName: string);

begin

    FName := AName;

end;

 

procedure TEquipment.Add(const AEquipment: TEquipment);

begin

    raise Exception.Create('不支持该方法');

end;

 

procedure TEquipment.Remove(const AEquipment: TEquipment);

begin

    raise Exception.Create('不支持该方法');

end;

 

function TEquipment.CreateIterator(): TIterator;

begin

    Result := nil;

end;

 

function TFloppyDisk.Power(): Integer;

begin

    Result := 1;

end;

 

function TFloppyDisk.NetPrice(): Currency;

begin

    Result := 1;

end;

 

function TFloppyDisk.DiscountPrice(): Currency;

begin

    Result := 1;

end;

 

constructor TCompositeEquipment.Create(const AName: string);

begin

    inherited;

    //---

    FEquipments := TObjectList.Create;

end;

 

destructor TCompositeEquipment.Destroy;

begin

    FEquipments.Free;

    //---

    inherited;

end;

 

function TCompositeEquipment.Power(): Integer;

var

    AIterator: TIterator;

begin

    AIterator := self.CreateIterator;

    try

        result := 0;

        with AIterator do

        begin

            First;

            while not IsDone do

            begin

                result := result + TEquipment(CurrentItem).Power;

                Next;

            end;

        end;

    finally

        AIterator.free;

    end;

end;

 

function TCompositeEquipment.NetPrice(): Currency;

var

    AIterator: TIterator;

begin

    AIterator := self.CreateIterator;

    try

        result := 0;

        with AIterator do

        begin

            First;

            while not IsDone do

            begin

                result := result + TEquipment(CurrentItem).NetPrice;

                Next;

            end;

        end;

    finally

        AIterator.free;

    end;

end;

 

function TCompositeEquipment.DiscountPrice(): Currency;

var

    AIterator: TIterator;

begin

    AIterator := self.CreateIterator;

    try

        result := 0;

        with AIterator do

        begin

            First;

            while not IsDone do

            begin

                result := result + TEquipment(CurrentItem).DiscountPrice;

                Next;

            end;

        end;

    finally

        AIterator.free;

    end;

end;

 

procedure TCompositeEquipment.Add(const AEquipment: TEquipment);

begin

    FEquipments.Add(AEquipment);

end;

 

procedure TCompositeEquipment.Remove(const AEquipment: TEquipment);

begin

    FEquipments.Remove(AEquipment);

end;

 

function TCompositeEquipment.CreateIterator:TIterator;

begin

    result := TListIterator.Create(FEquipments);

end;

 

function TChassis.Power(): Integer; //Watt

begin

    Result := inherited Power + 1;

end;

 

function TChassis.NetPrice(): Currency;

begin

    Result := inherited NetPrice + 1;

end;

 

function TChassis.DiscountPrice(): Currency;

begin

    Result := inherited DiscountPrice + 1;

end;

 

function TCabinet.Power(): Integer;

begin

    Result := inherited Power + 1;

end;

 

function TCabinet.NetPrice(): Currency;

begin

    Result := inherited NetPrice + 1;

end;

 

function TCabinet.DiscountPrice(): Currency;

begin

    Result := inherited DiscountPrice + 1;

end;

 

function TBus.Power(): Integer;

begin

    Result := inherited Power + 1;

end;

 

function TBus.NetPrice(): Currency;

begin

    Result := inherited NetPrice + 1;

end;

 

function TBus.DiscountPrice(): Currency;

begin

    Result := inherited DiscountPrice + 1;

end;

 

function TCard.Power(): Integer;

begin

    Result := 1;

end;

 

function TCard.NetPrice(): Currency;

begin

    Result := 1;

end;

 

function TCard.DiscountPrice(): Currency;

begin

    Result := 1;

end;

 

end.

 

procedure TForm1.Button1Click(Sender: TObject);

var

    Cabinet: TCabinet;

    Chassis: TChassis;

    Bus: TBus;

begin

    Cabinet := TCabinet.Create('PC Cabinet');

    try

        Chassis := TChassis.Create('PC Chassis');

        Cabinet.Add(Chassis);

        //---

        Bus := TBus.Create('MCA Bus');

        Bus.Add(TCard.Create('16Mbs Token Ring'));

        Chassis.Add(Bus);

        //---

        Chassis.Add(TFloppyDisk.Create('3.5in Floppy'));

        //---

        ShowMessage(CurrToStr(Cabinet.NetPrice));

    finally

        Cabinet.Free;

    end;

end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值