bauworld title

Ritorna alla pagina "Delphi"


Liste di oggetti omogenei e "pattern iterator"

La necessità di implementare una nuova classe per gestire delle liste di oggetti è nata dall'esigenza di avere delle collezioni che permettano solamente l'inserimento di oggetti che siano (o siano derivati) della stessa classe.
Questa collezione presenta essenzialmente le stesse proprietà della classe TList. In pratica la lista di oggetti viene gestita da una TList privata e i metodi sono ridefiniti dai metodi privati della TBauList.
Inoltre la lista è stata dotata di un pattern iterator, un meccanismo per scorrere gli elementi senza usare un indice integer. Per questo motivo la classe non contiene metodi per accedere alla lista tramite un indice.

Scarica l'esempio

Download BauList.rar

Implementazione

La definizione della classe derivata da TList è la seguente:

  TBauList = class
  private
    FItems: TList;
  protected
    function GetItem(Idx: Integer): TObject;
    function CheckItemType(const Item: TObject): boolean; virtual;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    procedure Add(const Item: TObject);
    procedure Insert(const Item, Before: TObject); overload;
    procedure Insert(Idx: Integer; const Item: TObject); overload;
    procedure Exchange(const Item1, Item2: TObject); overload;
    procedure Exchange(Idx1, Idx2: Integer); overload;
    procedure Delete(Idx: Integer);
    procedure Remove(const Item: TObject);
    procedure Clear;
    function Contains(const Item: TObject): Boolean;
    function GetCount: Integer;
    function GetIterator: TBauListIterator;
  end;

La classe TBauListIterator è l'oggetto che si occupa di scorrere gli elementi della lista, la quale viene fornita all'iteratore come parametro del metodo Create.

La definizione della classe per scorrere gli elementi della lista è la seguente:


  TBauListIterator = classprivate
    fList: TList;
    fCurrentItem: Integer;
  protected
    procedure ResetList;
  public                   
    constructor Create(const List: TList); virtual;
    function CurrentItem: TObject;
    function Next: Boolean;
    function Prev: Boolean;
    function First: Boolean;
    function Last: Boolean;
  end;

Qualcosa in più

A questo punto possiamo inserire un miglioria. Infatti l'obbligo di distruggere l'oggetto Iterator dopo l'uso potrebbe essere fonte di errore da parte di un eventuale utilizzatore che si dimentica di eseguire il free dell'oggetto. Per evitare ciò è necessario utilizzare una interfaccia che definisca la classe TBauListIterator:

  IBauListIterator = interface(IInterface)
  ['{AEA0E1B7-5495-4F7C-AE60-F7F5D62AD8EE}']
    procedure ResetList;
    function Next: Boolean;     
    function Prev: Boolean;
    function First: Boolean;
    function Last: Boolean;
    function CurrentItem: TObject;
  end;

Fatto questo bisogna modificare la dichiarazione di TBauListIterator:

TBauListIterator = class(TInterfacedObject,IBauListIterator)

TInterfacedObject introdurrà i metodi _AddRef e _Release, che provvederanno alla distruzione automatica degli oggetti non più utilizzati. Si potrà così scorrere la lista senza preoccuparsi di liberare l'oggetto Iterator quando avremo finito di usarlo.

Ritorna alla pagina "Delphi"