您的位置:首页 > 编程语言 > Delphi

《GOF设计模式》—迭代器 (ITERATOR)—Delphi源码示例:迭代器接口

2011-02-18 09:36 711 查看
示例:迭代器接口
说明:
(1)、定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

(2)、结构



 
迭代器:
Iterator(迭代器):迭代器定义访问和遍历元素的接口。
ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口。对该聚合遍历时跟踪当前位置。
聚合:
Aggregate(聚合):聚合定义创建相应迭代器对象的接口。
ConcreteAggregate(具体聚合):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
协作:
ConcreteIterator跟踪聚合中的当前对象,并能够计算出待遍历的后继对象。

代码:
unit uIterator1;

interface

uses
    SysUtils,Classes,Dialogs;

type
    TConcreteAggregate = class;

    TIterator = class
    public
        procedure First(); virtual; abstract;
        procedure Next(); virtual; abstract;
        function IsDone(): Boolean; virtual; abstract;
        function CurrentItem(): string; virtual; abstract;
    end;
    TConcreteIterator = class(TIterator)
    private
        FAggregate: TConcreteAggregate;
        FCurrent: integer;
    public
        constructor Create(const Aggregate: TConcreteAggregate);
        //---
        procedure First(); override;
        procedure Next(); override;
        function IsDone(): Boolean; override;
        function CurrentItem: string; override;
    end;

    TAggregate = class
    public
        function CreateIterator(): TIterator; virtual; abstract;
    end;

    TConcreteAggregate = class(TAggregate)
    private
        FList:TStringList;
        function GetCount: integer;
        function GetItems(Index: integer): string;
    public
        constructor Create;
        destructor Destroy; override;
        //---
        function CreateIterator: TIterator; override;
        procedure Add(s:string);
        //---
        property Count: integer read GetCount;
        property Items[Index: integer]: string read GetItems; default;
    end;
    
procedure Test;

implementation

procedure Test;
    //---
    procedure _ShowAggregate(I:TIterator);
    begin
        I.First;
        while not I.IsDone do
        begin
            ShowMessage(I.CurrentItem);
            I.Next;
        end;
    end;
var
    Aggregate: TConcreteAggregate;
    AIterator: TIterator;
begin
    Aggregate := TConcreteAggregate.Create;
    try
        with Aggregate do
        begin
            Add('111');
            Add('222');
            Add('333');
        end;
        //---
        AIterator := Aggregate.CreateIterator;
        _ShowAggregate(AIterator);
        AIterator.Free;
    finally
        Aggregate.Free;
    end;
end;

constructor TConcreteIterator.Create(const Aggregate: TConcreteAggregate);
begin
    FAggregate := Aggregate;
    FCurrent := 0;
end;

procedure TConcreteIterator.First;
begin
    FCurrent := 0;
end;

procedure TConcreteIterator.Next;
begin
    FCurrent := FCurrent + 1;
end;

function TConcreteIterator.IsDone: Boolean;
begin
    Result := FCurrent >= FAggregate.Count;
end;

function TConcreteIterator.CurrentItem: string;
begin
    if self.IsDone then
        raise Exception.Create('Iterator Out Of Bounds');
    //---
    Result := FAggregate.Items[FCurrent];
end;

constructor TConcreteAggregate.Create;
begin
    FList := TStringList.Create;
end;

destructor TConcreteAggregate.Destroy;
begin
    FList.Free;
    //---
    inherited;
end;

function TConcreteAggregate.CreateIterator: TIterator;
begin
    Result := TConcreteIterator.Create(self);
end;

function TConcreteAggregate.GetCount: integer;
begin
    Result := FList.Count;
end;

function TConcreteAggregate.GetItems(Index: integer): string;
begin
    Result := FList[Index];
end;

procedure TConcreteAggregate.Add(s: string);
begin
    FList.Add(s);
end;

end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐