Das Iterator-Muster ermöglicht dem Client über eine Datenstruktur zu gehen (zu iterieren) ohne dass der Klient wissen muss wie sich diese Datenstruktur aufbaut. Das bedeutet ich habe eine Schnittstelle über die ich auf die Daten zugreife und dem Client kann es egal sein, ob die Daten in einem Array, einer List oder wie auch immer vorliegen.
Meistens habe ich es mit Objekten zu tun, welche ich in einer TList verwalte. Zum Beispiel innerhalb eines Kompositums. Wenn nun mein Client damit was machen will (z. B. alle Artikel einer Rezeptur im Formular auflisten) erstellt das Kompositum einen Iteratur mit dessen Hilfe das Formular dann die Artikel auflisten kann.
Hier der Quellcode für den Iterator:
// ------------------------------
//
// Delphi Entwursmustersammlung -- Iterator
//
// Autor: Thomas Groeschke
// Erstellt: 12.08.2008
//
// ------------------------------
unit Iteratoren;
interface
uses Classes, Dialogs, sysutils, Contnrs;
type
IIterator = interface(IInterface)
procedure AddObj(iObj:TObject);
function Count: Integer;
function CurrentItem: TObject;
function First: TObject;
function HasNext: Boolean;
function Next: TObject;
function Prev: TObject;
end;
TListIterator = class(TInterfacedObject, IIterator)
strict private
FAggregate: TList;
Index: Integer;
public
constructor Create(iValues:TList);
destructor Destroy; override;
procedure AddObj(iObj:TObject);
function Count: Integer;
function CurrentItem: TObject;
function First: TObject;
function HasNext: Boolean;
function Next: TObject;
function Prev: TObject;
end;
implementation
constructor TListIterator.Create(iValues:TList);
var
i: Integer;
begin
inherited Create;
FAggregate := TList.Create;
if iValues <> nil then
for i := 0 to iValues.Count - 1 do
AddObj(iValues[i]);
Index := -1;
end;
destructor TListIterator.Destroy;
begin
FAggregate.Free;
Inherited;
end;
procedure TListIterator.AddObj(iObj:TObject);
begin
FAggregate.Add(iObj);
end;
function TListIterator.Count: Integer;
begin
result := TList(FAggregate).Count;
end;
function TListIterator.CurrentItem: TObject;
begin
if TList(FAggregate).Count <> 0 then
result := TList(FAggregate).Items[Index]
else
result := nil;
end;
function TListIterator.First: TObject;
begin
if TList(FAggregate).Count <> 0 then
begin
result := TList(FAggregate).Items[0];
Index := 0;
end
else
begin
result := nil;
Index := -1;
end;
end;
function TListIterator.HasNext: Boolean;
begin
if TList(FAggregate).Count > Index + 1 then
result := true
else
result := false;
end;
function TListIterator.Next: TObject;
begin
if HasNext then
begin
Inc(Index);
result := TList(FAggregate).Items[Index];
end
else
result := nil;
end;
function TListIterator.Prev: TObject;
begin
if Index - 1 > 0 then
begin
dec(Index);
result := TList(FAggregate).Items[Index];
end
else
result := nil;
end;
Quergecheckt (Links zum Thema):
Wie werde ich ein Interface wieder los?
Wikibooks: Muster Iterator