Der Iterator

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

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>