Best practice per l'implementazione di MVVM e MVC in delphi Pascal


10

Sono un programmatore di Delphi pascal, utilizzo l'ultimo Embarcadero delphi XE e vorrei sfruttare i modelli di progettazione come il controller vista modello e il modello vista modello.

Tuttavia, non sembra esserci molto sul web riguardo alle migliori pratiche per farlo in pascal. La maggior parte degli esempi che posso trovare sono in C # e alcune delle funzionalità del linguaggio non sono presenti in Pascal, il che significa che potrebbe essere necessario trovare modi per implementare tali funzionalità.

Sto cercando di adattare il codice da questo articolo qui

Elencherò i problemi che sto affrontando

  • Tipi nullabili

Pascal non ha tipi nullable come C #, quindi ne ho creato uno mio.

TNullable<T> = record
    strict private
      fHasValue : boolean;
      fValue : T;
      function GetValue:T;
      procedure SetValue(newValue : T);
    public
      property HasValue : boolean read fHasValue;
      property Value : T read GetValue write SetValue;
      procedure SetToNull;
    end;

nella sezione di implementazione

function TNullable<T>.GetValue:T;
begin
    if fHasValue then
    begin
        Result := fValue;
    end
    else raise Exception.Create('Value Not Set');
end;

procedure TNullable<T>.SetValue(newValue : T);
begin
    fValue := newValue;
    fHasValue := true;
end;

procedure TNullable<T>.SetToNull;
begin
    fHasValue := false;
end;
  • Ottieni / Imposta per proprietà

Ora che ho un tipo nullable posso creare proprietà nullable Tuttavia viene fornito con alcuni odori di codice

per esempio se creo

    TFoo = class
      private
        function GetBar:TNullable<Integer>;
        procedure SetBar(x:TNullable<Integer>);
      public 
        property Bar : TNullable<Integer> read GetBar write SetBar;

nella sezione di implementazione

function TFoo.GetBar:TNullable<Integer>;
begin
    if **valueExists** then
    begin
        Result.Value := **the value**
    end else
    begin
        Result.SetToNull;
    end;
end;

procedure TFoo.SetBar(x:TNullable<Integer>);
begin
    if X.hasValue then
    begin
        //Store/show value here
    end else
    begin
        //handle null assignment here
    end;
end;

Questo va bene, ma quando si tratta di utilizzare queste proprietà non posso semplicemente usare

myFoo.Bar.Value: = 1;

Devo usare

var 
    myBar : TNullable<Integer>;
begin
    myBar.Value := 1;
    myFoo.Bar := myBar;
end;

Che è un po 'più disordinato. Suppongo che non ci possa essere nulla che io possa fare al riguardo.

  • Riferimenti circolari

Mi piace separare le classi in unità diverse.

vale a dire: struttura

mantenendo l'interfaccia utente separata dalla logica di controllo e dal livello della logica dei dati e del modello.

Posso avere una situazione in cui 2 classi possono fare riferimento a vicenda. Mentre questa è una situazione che per la maggior parte vorrei evitare, ci sono occasioni in cui è necessario.

per esempio

unit u_A;

interface

uses
  u_B
  ;

type 
  TA = class
    public
       Foo : TB;
  end;

implementation

end;

e un'altra unità

unit u_B;

interface

uses
  u_A
  ;

type 
  TB = class
    public
       Foo : TA;
  end;

implementation

end;

Questo codice è rotto perché le due classi si includono e ciò non può essere fatto in Pascal. Questo non è un problema in C #. Soluzioni a cui riesco a pensare: 1. includi entrambe le classi nella stessa unità, anche se questo è un problema se non penso che sia adatto al design. 2. Crea un'altra interfaccia genitore per B ed eredita B da quello, quindi questo lo aggira. Anche se questo è disordinato per un compito così semplice.

  • Classi statiche

Non ci sono classi statiche in Delphi, sono utili per le classi di controllo.

  • Le migliori classi di container da utilizzare in Delphi

Attualmente sto usando TList e TObjectList in Generics.Collections Sono stati introdotti in Delphi XE Spero che siano i migliori da usare poiché Delphi 7 non sembra avere buone opzioni.

Sto ancora pensando ai gestori di eventi e agli eventuali problemi che potrebbero sorgere lì. Forse ci sono altri problemi a cui non ho ancora pensato.

Grazie per qualsiasi consiglio


Inizialmente avevo posto questa domanda sulla revisione del codice, ma mi è stato suggerito di postare qui.
salva il

Risposte:


9

Dovresti esaminare Spring4D in quanto contiene già tipi nullable (implementazione simile alla tua con un piccolo sovraccarico dell'operatore) e tipi di raccolta molto più potenti di quelli in RTL. Sono anche basati su interfacce, il che è molto utile perché non devi preoccuparti della gestione della vita, specialmente quando li passi in giro.

Per problemi di riferimento incrociato sto suggerendo la codifica rispetto alle interfacce e le uso come riferimento in un'altra implementazione anziché in 2 implementazioni che si conoscono.

Per quanto riguarda la parte MVVM potresti guardare in DSharp che ha una prima versione di una porta Micro di Caliburn per Delphi. È una fase molto precoce e difficilmente documentata, ma potresti avere alcune idee su come ottenere MVVM in Delphi usando una GUI liberamente allentata e una logica aziendale connessa con i collegamenti dei dati. La rivista Blaise Pascal aveva due articoli a riguardo se sei più interessato.

PS Immagino che intendi che stai usando XE6 come quella è l'ultima versione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.