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:
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.
Antworten:
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.
quelle