《GOF设计模式》—迭代器 (ITERATOR)—Delphi源码示例:内部迭代器(封装不同类型的迭代)

来源:互联网 发布:java编程规范 pdf 编辑:程序博客网 时间:2024/05/02 04:49

示例:封装不同类型的迭代
实现:
内部迭代器可以封装不同类型的迭代。例如,FilteringListTraverser封装的迭代仅处理能通过测试的那些列表元素。这个类接口除了增加了用于测试的成员函数TestItem外与ListTraverser相同,它的子类将重定义TestItem以指定所需的测试。Traverse根据测试的结果决定是否越过当前元素继续遍历。
这个类的一中变体是让Traverse返回值指示是否至少有一个元素通过测试。

代码:
unit uFilteringListTraverser;

interface

uses uList,uListIterator;

type
    TFilteringListTraverser = class
    private
        FIterator: TListIterator;
    protected
        function ProcessItem(AItem: TObject): Boolean; virtual; abstract;
        function TestItem(AItem: TObject): boolean; virtual; abstract;
    public
        constructor Create(AList: TList1);
        destructor Destroy; override;
        //---
        function Traverse(): Boolean;
    end;

implementation

{ TFilteringListTraverser }

constructor TFilteringListTraverser.Create(AList: TList1);
begin
    FIterator := TListIterator.Create(AList);
end;

destructor TFilteringListTraverser.Destroy;
begin
    FIterator.Free;
    //---
    inherited;
end;

function TFilteringListTraverser.Traverse: Boolean;
begin
    Result := false;
    //---
    with FIterator do
    begin
        First;
        while not IsDone do
        begin
            if TestItem(CurrentItem) then
            begin
                Result := ProcessItem(CurrentItem);
                if not Result then
                    break;
            end;
            //---
            Next;
        end;
    end;
end;

end.

unit uPrintNEmployees1;

interface

uses uList,uFilteringListTraverser;

type
    TPrintNEmployees1 = class(TFilteringListTraverser)
    protected
        function ProcessItem(AItem: TObject): Boolean; override;
        function TestItem(AItem: TObject): boolean; override;
    end;

implementation

uses uEmployee;

function TPrintNEmployees1.ProcessItem(AItem: TObject): Boolean;
begin
    TEmployee(AItem).Print;
    Result := true;
end;

function TPrintNEmployees1.TestItem(AItem: TObject): boolean;
begin
    Result := Length(TEmployee(AItem).Name) >= 2;
end;

end.

procedure TForm1.Button6Click(Sender: TObject);
var
    AEmployees: TList1;
    pa: TPrintNEmployees1;
begin
    self.Memo1.Clear;
    //---
    AEmployees := TList1.Create;
    try
        with AEmployees do
        begin
            Add(TEmployee.Create('1',self.Memo1));
            Add(TEmployee.Create('22',self.Memo1));
            Add(TEmployee.Create('3',self.Memo1));
            Add(TEmployee.Create('44',self.Memo1));
        end;
        //---
        pa := TPrintNEmployees1.Create(AEmployees);
        pa.Traverse;
        pa.Free;
    finally
        AEmployees.Free;
    end;
end;

原创粉丝点击