Best Practices für die Implementierung von MVVM und MVC in delphi Pascal

10

Ich bin ein Delphi-Pascal-Programmierer, verwende das neueste Embarcadero delphi XE und möchte Entwurfsmuster wie Model View Controller und Model View View-Model nutzen.

Es scheint jedoch nicht viel im Web über die Best Practices zu geben, um dies in Pascal zu tun. Die meisten Beispiele, die ich finden kann, befinden sich in C #, und einige der Sprachfunktionen sind in Pascal nicht vorhanden. Dies bedeutet, dass ich möglicherweise Wege finden muss, um diese Funktionen zu implementieren.

Ich versuche , Code aus diesem Artikel anzupassen hier

Ich werde die Probleme auflisten, mit denen ich konfrontiert bin

  • Nullable Typen

Pascal hat keine nullbaren Typen wie C #, daher habe ich meine eigenen erstellt.

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;

im Implementierungsabschnitt

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;
  • Get / Set für Eigenschaften

Jetzt, wo ich einen nullbaren Typ habe, kann ich nullbare Eigenschaften erstellen. Es kommt jedoch mit einigen Code-Gerüchen

Zum Beispiel, wenn ich erschaffe

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

im Implementierungsabschnitt

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;

Das ist in Ordnung, aber wenn es darum geht, diese Eigenschaften zu nutzen, kann ich sie nicht einfach nutzen

myFoo.Bar.Value: = 1;

Ich muss benutzen

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

Welches ist ein bisschen chaotischer. Ich nehme an, ich kann nichts dagegen tun.

  • Rundschreiben

Ich mag es, Klassen in verschiedene Einheiten zu unterteilen.

dh: Struktur

Halten Sie die Benutzeroberfläche von der Steuerlogik und der Modell- und Datenlogikschicht getrennt.

Ich kann eine Situation haben, in der 2 Klassen aufeinander verweisen können. Während dies eine Situation ist, die ich größtenteils vermeiden möchte, gibt es Fälle, in denen dies erforderlich ist.

beispielsweise

unit u_A;

interface

uses
  u_B
  ;

type 
  TA = class
    public
       Foo : TB;
  end;

implementation

end;

und eine andere Einheit

unit u_B;

interface

uses
  u_A
  ;

type 
  TB = class
    public
       Foo : TA;
  end;

implementation

end;

Dieser Code ist fehlerhaft, da sich die beiden Klassen gegenseitig einschließen und dies nicht in Pascal möglich ist. Dies ist in C # kein solches Problem. Lösungen, die mir einfallen: 1. Schließen Sie beide Klassen in dieselbe Einheit ein, obwohl dies ein Problem ist, wenn ich nicht denke, dass dies zum Design passt. 2. Erstellen Sie eine weitere übergeordnete Schnittstelle für B und erben Sie B davon. Dann wird dies umgangen. Obwohl dies für eine so einfache Aufgabe chaotisch ist.

  • Statische Klassen

In Delphi gibt es keine statischen Klassen. Diese sind nützlich für Kontrollklassen.

  • Beste Containerklassen für Delphi

Ich verwende derzeit TList und TObjectList in Generics.Collections. Sie wurden in Delphi XE eingeführt. Ich hoffe, diese sind die besten, da Delphi 7 keine guten Optionen zu haben schien.

Ich denke immer noch an Event-Handler und alle Probleme, die dort auftreten können. Vielleicht gibt es noch einige andere Probleme, an die ich noch nicht gedacht habe.

Vielen Dank für jeden Rat.

sav
quelle
Ich habe diese Frage ursprünglich bei der Codeüberprüfung gestellt, aber es wurde vorgeschlagen, dass ich hier poste.
Sav

Antworten:

9

Sie sollten sich Spring4D ansehen, da es bereits nullfähige Typen enthält (ähnliche Implementierung wie Ihre mit etwas zusätzlicher Operatorüberladung) und weitaus leistungsfähigere Sammlungstypen als die in der RTL. Sie basieren auch auf Schnittstellen, was sehr praktisch ist, da Sie sich keine Gedanken über die Lebensdauerverwaltung machen müssen, insbesondere wenn Sie sie weitergeben.

Bei Querverweisproblemen schlage ich vor, Codierungen für Schnittstellen durchzuführen und diese als Referenz in einer anderen Implementierung zu verwenden, anstatt zwei Implementierungen zu kennen, die sich kennen.

Was den MVVM-Teil betrifft, könnten Sie sich DSharp ansehen, das eine erste Version eines Caliburn Micro-Ports für Delphi enthält. Es ist ein sehr frühes Stadium und kaum dokumentiert, aber Sie erhalten möglicherweise einige Ideen, wie Sie MVVM in Delphi mithilfe einer lose gekoppelten GUI und Geschäftslogik erreichen können, die mit Datenbindungen verbunden sind. Das Blaise Pascal Magazin hatte zwei Artikel darüber, wenn Sie mehr interessiert sind.

PS Ich denke, Sie meinen, Sie verwenden XE6, da dies die neueste Version ist.

Stefan Glienke
quelle