DesignPatterns. Iterator

Простой пример итератора для коллекции

program IteratorPattern;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uIterator in 'uIterator.pas';

var
  c: TCollection;
  i: TCustomIterator;

begin
  c := TCollection.Create();
  try
    c.Add(TStrObjForTest.Create('obj 1'));
    c.Add(TStrObjForTest.Create('obj 2'));
    c.Add(TStrObjForTest.Create('obj 3'));
    // iteration
    i := TCustomIterator.Create(c);
    try
      Writeln(TStrObjForTest(i.First).Value);
      while not i.IsDone do
        Writeln(TStrObjForTest(i.Next).Value);
      Readln;
    finally
      i.Free();
    end;
  finally
    c.Free();
  end;
end.

Модуль итератора

unit uIterator;

interface

uses
  System.Contnrs;

type
  TIterator = class
  public
    function First(): TObject; virtual; abstract;
    function Next(): TObject; virtual; abstract;
    function IsDone(): Boolean; virtual; abstract;
    function CurrentItem(): TObject; virtual; abstract;
  end;

  TCollection = class
  private
    FItems: TObjectList;
    FIterator: TIterator;
    function GetCount: Integer;
    function GetItem(aIndex: integer): TObject;
  public
    constructor Create();
    destructor Destroy; override;
    procedure Add(aObject: TObject);
    property Iterator: TIterator read FIterator;
    property Count: integer read GetCount;
    property Items[aIndex: Integer]: TObject read GetItem; default;
  end;

  TCustomIterator = class(TIterator)
  private
    FCollection: TCollection;
    FCurrentIndex: integer;
  public
    constructor Create(aCollection: TCollection);
    function First(): TObject; override;
    function Next(): TObject; override;
    function IsDone(): Boolean; override;
    function CurrentItem(): TObject; override;
  end;

  TStrObjForTest = class
  private
    FValue: string;
  public
    constructor Create(aValue: string);
  public
    property Value: string read FValue;
  end;

implementation

uses
  System.SysUtils;

{ TCollection }

procedure TCollection.Add(aObject: TObject);
begin
  if aObject = nil then
    raise Exception.Create('obj is nil');
  FItems.Add(aObject);
end;

constructor TCollection.Create;
begin
  FIterator := TIterator.Create();
  FItems := TObjectList.Create(true);
end;

destructor TCollection.Destroy;
begin
  FIterator.Free();
  FItems.Free();
  inherited;
end;

function TCollection.GetCount: Integer;
begin
  Result := FItems.Count;
end;

function TCollection.GetItem(aIndex: integer): TObject;
begin
  Result := FItems[aIndex];
end;


{ TCustomIterator }

constructor TCustomIterator.Create(aCollection: TCollection);
begin
  FCurrentIndex := 0;
  if aCollection <> nil then
    FCollection := aCollection;
end;

function TCustomIterator.CurrentItem: TObject;
begin
  Result := FCollection[FCurrentIndex];
end;

function TCustomIterator.First: TObject;
begin
  if FCollection[0] = nil then
    raise Exception.Create('obj is nil');
  Result := FCollection[0];
end;

function TCustomIterator.IsDone: Boolean;
begin
  Result := FCurrentIndex >= FCollection.Count - 1;
end;

function TCustomIterator.Next: TObject;
begin
  Result := nil;

  Inc(FCurrentIndex);
  if FCurrentIndex < FCollection.Count then
    Result := FCollection[FCurrentIndex];
end;

{ TStrObj }

constructor TStrObjFOrTest.Create(aValue: string);
begin
  FValue := aValue;
end;

end.
This entry was posted in Без рубрики. Bookmark the permalink.