Je suis un programmeur Pascal Delphi, j'utilise le dernier Embarcadero delphi XE, et je voudrais profiter des modèles de conception tels que le contrôleur de vue du modèle et le modèle de vue du modèle.
Cependant, il ne semble pas y avoir beaucoup sur le web sur les meilleures pratiques pour le faire en pascal. La plupart des exemples que je peux trouver sont en C # et certaines fonctionnalités du langage ne sont pas présentes dans pascal, ce qui signifie que je devrai peut-être trouver des moyens de mettre en œuvre ces fonctionnalités.
J'essaie d'adapter le code de cet article ici
Je vais lister les problèmes auxquels je suis confronté
- Types nullables
Pascal n'a pas de types Nullable comme C #, donc j'ai créé le mien.
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;
dans la section de mise en œuvre
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;
- Obtenir / définir pour les propriétés
Maintenant que j'ai un type Nullable, je peux créer des propriétés Nullable Cependant, il est livré avec quelques odeurs de code
par exemple si je crée
TFoo = class
private
function GetBar:TNullable<Integer>;
procedure SetBar(x:TNullable<Integer>);
public
property Bar : TNullable<Integer> read GetBar write SetBar;
dans la section de mise en œuvre
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;
C'est bien mais quand il s'agit d'utiliser ces propriétés, je ne peux pas simplement utiliser
myFoo.Bar.Value: = 1;
Je dois utiliser
var
myBar : TNullable<Integer>;
begin
myBar.Value := 1;
myFoo.Bar := myBar;
end;
Ce qui est un peu plus compliqué. Je suppose que je ne peux rien y faire.
- Références circulaires
J'aime séparer les classes en différentes unités.
c'est à dire:
garder l'interface utilisateur distincte de la logique de contrôle et de la couche logique de modèle et de données.
Je peux avoir une situation où 2 classes peuvent se référencer. Bien que ce soit une situation que j'aimerais éviter pour la plupart, il y a des occasions où cela est nécessaire.
par exemple
unit u_A;
interface
uses
u_B
;
type
TA = class
public
Foo : TB;
end;
implementation
end;
et une autre unité
unit u_B;
interface
uses
u_A
;
type
TB = class
public
Foo : TA;
end;
implementation
end;
Ce code est cassé car les deux classes s'incluent et cela ne peut pas être fait en pascal. Ce n'est pas un tel problème en C #. Solutions auxquelles je peux penser: 1. inclure les deux classes dans la même unité, bien que ce soit un problème si je ne pense pas que cela convient à la conception. 2. Créez une autre interface parent pour B et héritez-en de B, puis cela contourne. Bien que ce soit compliqué pour une tâche aussi simple.
- Classes statiques
Il n'y a pas de classes statiques dans Delphi, elles sont utiles pour les classes de contrôle.
- Meilleures classes de conteneurs à utiliser dans Delphi
J'utilise actuellement TList et TObjectList dans Generics.Collections Ils ont été introduits dans Delphi XE J'espère que ce sont les meilleurs à utiliser car delphi 7 ne semblait pas avoir de bonnes options.
Je pense toujours aux gestionnaires d'événements et à tout problème qui pourrait survenir. Il y a peut-être d'autres problèmes auxquels je n'ai pas encore pensé.
Merci pour tout conseil.
Réponses:
Vous devriez examiner Spring4D car il contient déjà des types nullables (implémentation similaire à la vôtre avec un peu de surcharge d'opérateur supplémentaire) et des types de collection bien plus puissants que ceux de la RTL. Ils sont également interfacés, ce qui est très pratique car vous n'avez pas à vous soucier de la gestion de la vie, en particulier lorsque vous les passez.
Pour les problèmes de références croisées, je suggère de coder par rapport aux interfaces et de les utiliser comme référence dans une autre implémentation plutôt que 2 implémentations se connaissant.
En ce qui concerne la partie MVVM, vous pourriez examiner DSharp qui a une première version d'un port Caliburn Micro pour Delphi. C'est un stade très précoce et peu documenté, mais vous pourriez avoir des idées sur la façon de réaliser MVVM dans Delphi en utilisant une interface graphique et une logique métier faiblement couplées connectées à des liaisons de données. Le magazine Blaise Pascal avait deux articles à ce sujet si vous êtes plus intéressé.
PS Je suppose que vous voulez dire que vous utilisez XE6 car c'est la dernière version.
la source