Uso Inteface con delphi

di il
1 risposte

Uso Inteface con delphi

Buonasera a tutti.
Visto le ultime zone "arancio rafforzate" mi ritrovo qualche ora libera e mi ritorna la voglia di "giocare" con Delphi.
Vorrei costruire un RPG ispirato al vecchio MERP, dunque ho preso carta e matita e ho iniziato a graficare le varie idee e
mi ritrovo nella situazione di avere almeno 3 classi base:
1) TWorld
2) TMap
3) TElement (Torri, Dungeon, Cave, Villaggi, ect ect )
Oltre ovviamente a quelle dei personaggi, ma non ci sono ancora arrivato.
Cmq queste 3 classi (volendo tenerle divise) si intrecciano tra di loro e solo a pensare ai vari "circular reference" mi vengono gli incubi, dunque
avrei pensato all'uso delle interfacce, ma ovviamente per un semplice hobbysta è come imparare il turco in qualce secondo, cmq ho
studiato (diciamo che ho usato il "bignami" di Marco Cantu "Object Pascal HandBook D10.4" ).
Da qui ho preso qualche spunto.
Qualche anima pia che probabilmente ci capisce più di me saprebbe dirmi se sono nella strada giusta.
Grazie

Di seguito includo i vari pezzi di codice che al momento sono più sulla carta che ....

La unit base delle interfacce

unit u.intf;

interface

uses u.TypeInfo;  // dichiarazioni comuni

type
  IElement = interface
    ['{0DBB9EE1-8899-4636-AB64-10923272EDD6}']
    Procedure Initialize;  // inizializzazione del labirinto
  end;

  IMap = interface
    ['{73B64E91-79B8-4D09-98D0-537B0E2D31B5}']
  End;

  IWorld = interface
  ['{B984A27E-FD31-4638-9317-CE1E881721CE}']
    Function Getdungeon: aDungeon;  // array [X,Y]
    Function GetdungeonPosition: aCoordinates; // tpoint x + y
    Function GetdungeonRoom: Integer;
    Function GetMap: IMap;    // riferimento alla mappa

    Procedure Setdungeon(Const Value: aDungeon);
    Procedure SetdungeonPosition(Const Value: aCoordinates);
    Procedure SetdungeonRoom(Const Value: Integer);
    Procedure SetMap(Const Value: IMap);

    property dungeon: aDungeon read Getdungeon write Setdungeon;
    property dungeonPosition: aCoordinates read GetdungeonPosition write SetdungeonPosition;
    Property dungeonRoom: Integer read GetdungeonRoom write SetdungeonRoom;
    property oMap: IMap read GetMap write SetMap;
  end;
La classe tworld

unit u.world;

interface

uses  u.intf  // riferimento alle interfacce
    , u.TypeInfo  // dichiarazioni comuni
    ;

type
  TWorld = class(TInterfacedObject, IWorld)
  private
    foMap: IMap;
    fodungeon: aDungeon;
    fodungeonPosition: aCoordinates;
    fodungeonRoom: Integer;

    Function Getdungeon: aDungeon;  // array [X,Y]
    Function GetdungeonPosition: aCoordinates; // tpoint x + y
    Function GetdungeonRoom: Integer;
    Function GetMap: IMap;    // riferimento alla mappa
    Procedure Setdungeon(Const Value: aDungeon);
    Procedure SetdungeonPosition(Const Value: aCoordinates);
    Procedure SetdungeonRoom(Const Value: Integer);
    Procedure SetMap(Const Value: IMap);
  public
    property dungeon: aDungeon read Getdungeon write Setdungeon;
    property dungeonPosition: aCoordinates read GetdungeonPosition write SetdungeonPosition;
    Property dungeonRoom: Integer read GetdungeonRoom write SetdungeonRoom;
    property oMap: IMap read GetMap write SetMap;
  end;
  --- ometto le implementazioni
le altre classi sono simili, la chiamata principale

  MainWorld := TWorld.Create;
  MainMap   := TMap.Create(GraphCDS);  // uso un CDS per caricare le bitmap
  Cave_Alpha := TCave.Create;    // questa è un IElement
  MainWorld.oMap := MainMap;      // la mappa sul mondo
  MainMap.oWorld := MainWorld;    // il mondo sulla mappa
  Cave_Alpha.oMap := MainMap;     // Test per un elemento di tipo cava sulla mappa
  Cave_Alpha.oWorld := MainWorld; // assegno il mondo alla cave ... anche se ci posso arrivare dalla mappa
  MainMap.oCave := Cave_Alpha;    // e viceversa  ... per ora singolo ma pensavo a lista di generici
  MainMap.SetupMap;               // inizializzo tutto
  
Il mio problema è soprattutto questo .... tutte queste assegnazioni non mi piaciono, esiste qualcosa di più "pulito", sto seguendo la strada giusta ??

Un Saluto N.

1 Risposte

  • Re: Uso Inteface con delphi

    Nettuno95 ha scritto:


    Cmq queste 3 classi (volendo tenerle divise) si intrecciano tra di loro e solo a pensare ai vari "circular reference" mi vengono gli incubi, dunque avrei pensato all'uso delle interfacce [...]
    Qualche anima pia che probabilmente ci capisce più di me saprebbe dirmi se sono nella strada giusta.
    Diciamo che, descritto in modo così generale, non è facile darti un consiglio su come realizzare il tuo RPG senza sapere che legami vuoi costruire tra i tuoi elementi e come questi devono interagire.

    Quello che posso dire è che, usate in quel modo, le interfacce sono poco efficaci: di fatto hai creato N interfacce che sono la versione astratta della classe (unica) che implementano, quindi questo approccio non introduce particolari vantaggi.

    Il termine per quella tipologia di interfacce è "asfittica", ossia che viola il principio di .

    Secondo me, è più conveniente che tu scriva prima un prototipo gettando il codice in base alle necessità implementative, e poi tu veda in corso d'opera i punti che possono essere fattorizzati, altrimenti rischi di peccare di "over engineering" e di creare tante cose astratte che poi non cooperano o non arrivano mai a una implementazione che funzioni.

    Come suggerimento, approfondisci i principi SOLID e le pratiche di Unit Testing (relativamente alla questione di introdurre feature e mantenere ordinato il codice requisito dopo requisito), e le interfacce o altri strumenti utili verranno da soli, con un po' di esperienza.

    Ciao!
Devi accedere o registrarti per scrivere nel forum
1 risposte