Простой пример итератора для коллекции
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.