デルファイ:ファクトリ関数対録音コンストラクタ
-
12-09-2019 - |
質問
だから何レコードを初期化する好ましい方法になりますか?
'ファクトリ関数' でます:
TMyRecord = record
valueX: integer;
valueY: integer;
end;
function MyRecord(const AValueX, AValueY: integer): TMyRecord;
begin
result.valueX := AValueX;
result.valueY := AValueY;
end;
var
myrec: TMyRecord;
begin
myrec := MyRecord(1, 2);
end;
またはコンストラクタます:
TMyRecord = record
valueX: integer;
valueY: integer;
constructor Create(const AValueX, AValueY: integer);
end;
constructor TMyRecord.Create(const AValueX, AValueY: integer);
begin
self.valueX := AValueX;
self.valueY := AValueY;
end;
var
myrec: TMyRecord;
begin
myrec := TMyRecord.Create(1, 2);
end;
私は、コンストラクタ物事をよりカプセル化されたことを感じるが、コードを読むときには、混乱することが容易になります。それは自由への呼び出しが不足しているクラスのように見えます。それはまた、より多くのだタイプに...
なぜあなたは他の上の1つを好むでしょうか?
解決
私は、クラスを好むが、私はレコードを使用する必要がある場合、私は可能なクラスと同様として扱うのが好き。だから私は、レコードのコンストラクタを使用します。
しかし、レコードやユニットでの迷惑なバグがあります。関数は(メソッドを持つ)レコードを返す場合は、これらのメソッドにアクセスする場合、それは内部エラーを生成します。あなたが別の変数に割り当てることによって、これを回避することができます:
type
TMyRec = record
..
procedure X;
end;
function GetRec: TMyRec;
procedure Test;
var
r1, r2 : TMyRec;
begin
r1 := GetRec;
r1.X; // internal error
r2 := r1;
r2.X; // No internal error;
他のヒント
私は
のように "ファクトリメソッド" を好みます function TMyRecord.CreateRec(const AValueX, AValueY: integer): TMyRecord;
セパレートファクトリ関数は、カプセル化し、レコードコンストラクタはただ私見を混同リークします。
私が作成したDelphiのプロジェクトで、私は、リスト上のオーバーヘッドの量を減らす代わりに、クラスのレコードを使用していました。私は2つのレコードを作成したので、私は、動的配列内のレコードの数百を持っているでしょう。 最初のレコードは、アイテム自体のためでした。フィールドはプライベートに(はい、あなたは、レコードで保護/プライベートを使用することができます)とパブリックセクションに読み取り専用プロパティを追加しました。追加のコンストラクタも正しい方法でレコードを初期化するために追加されました。このセットアップは私が他の開発者からこのレコードから内容物を保護することができました。 第二のレコードは、前のレコード・タイプのダイナミックアレイの周りだけのラッパーでした。配列は、プライベートだろうと私は、取得このリストにレコードを追加および削除するためのメソッドを追加しました。その結果、全体のリストは、他の開発者による誤使用から保護し、また定期的なのTList / TObjectListをソリューションよりもはるかに少ないオーバーヘッドを持っています。
レコードはクラスではないことを心に留めておくようにしてください。あなたは、コンストラクタや他のメソッドを継承することはできません。彼らは、WIN32環境における真のクラスよりも少ない機能を持っています。 .NETでは、彼らは再びクラスに昇格しています。 そして、それは、開発者が簡単にあなたのレコードにそれぞれすべてのフィールドの内容を変更することができたときにコンストラクタを追加使用することは非常に便利ではありません。代わりに、これらのフィールドを保護するためのコンストラクタを使用する必要があります。
私は通常のレコードのコンストラクタを作成しないでください。これは、すべてのバージョン(およびFPC)との互換性はありません。また一般的に、彼らは一つの場所でのみ使用され、多くの場合、fillcharは十分です。