私はDelphi Pascalプログラマーで、最新のEmbarcadero delphi XEを使用しています。モデルビューコントローラーやモデルビュービューモデルなどのデザインパターンを利用したいと思います。
ただし、Pascalでこれを行うためのベストプラクティスについては、Webにはあまり多くありません。私が見つけることができるほとんどの例はC#にあり、一部の言語機能はPascalにはありません。つまり、これらの機能を実装する方法を見つける必要があるかもしれません。
私はこの記事のコードを適応させようとしています here
私が直面している問題をリストします
PascalにはC#のようにnull許容型がないため、独自に作成しました。
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;
実装セクション
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;
Null可能な型ができたので、null可能なプロパティを作成できますが、コードの匂いがいくつかあります
たとえば私が作成した場合
TFoo = class
private
function GetBar:TNullable<Integer>;
procedure SetBar(x:TNullable<Integer>);
public
property Bar : TNullable<Integer> read GetBar write SetBar;
実装セクション
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;
これは問題ありませんが、これらのプロパティを使用する場合、私は単に使用することはできません
myFoo.Bar.Value:= 1;
私は使用する必要があります
var
myBar : TNullable<Integer>;
begin
myBar.Value := 1;
myFoo.Bar := myBar;
end;
少し厄介です。これについて私にできることは何もないかもしれません。
クラスを異なるユニットに分けるのが好きです。
つまり:
ユーザーインターフェイスを制御ロジック、モデルおよびデータロジックレイヤーから分離します。
2つのクラスが相互に参照できる状況になることがあります。これはほとんどの場合回避したい状況ですが、これが必要になる場合があります。
例えば
unit u_A;
interface
uses
u_B
;
type
TA = class
public
Foo : TB;
end;
implementation
end;
そして別のユニット
unit u_B;
interface
uses
u_A
;
type
TB = class
public
Foo : TA;
end;
implementation
end;
2つのクラスが互いに含まれているため、このコードは壊れています。これはPascalでは実行できません。これはC#ではそのような問題ではありません。考えられる解決策:1.両方のクラスを同じユニットに含めます。ただし、これが設計に適さないと思われる場合は問題です。 2. Bの別の親インターフェースを作成し、そこからBを継承すると、これが回避されます。これはそのような単純なタスクには厄介ですが。
Delphiには静的クラスはありません。これらはコントロールクラスに役立ちます。
私は現在Generics.CollectionsでTListとTObjectListを使用しています。これらはDelphi XEで導入されました。delphi7には適切なオプションがないようだったので、これらが使用するのに最適であることを願っています。
私はまだイベントハンドラーとそこで発生する可能性のある問題について考えています。おそらく、まだ考えていない他の問題があるかもしれません。
アドバイスありがとうございます。
Spring4Dには、null許容型(演算子のオーバーロードを少し追加したものと同様の実装)とRTLよりも強力なコレクション型が含まれているため、調べてください。それらはまた、特にそれらを渡すときに寿命管理について心配する必要がないので非常に便利なインターフェースベースです。
相互参照の問題については、インターフェースに対するコーディングを提案し、2つの実装がお互いを認識しているのではなく、これらを参照として別の実装で使用することをお勧めします。
MVVMの部分については、Delphi用のCaliburn Microポートの最初のバージョンがあるDSharpを調べてみてください。これは非常に初期の段階であり、ほとんど文書化されていませんが、データバインディングに接続された疎結合GUIとビジネスロジックを使用してDelphiでMVVMを実現する方法についていくつかのアイデアを得るかもしれません。 Blaise Pascal誌には、興味があれば2つの記事が掲載されています。
追伸XE6を使用しているのではないでしょうか。それが最新バージョンです。