3

field私は最近さまざまなクラスを書いていますが、うっかりとproperty識別子の両方を使用して読み書きしていることに気付きました。

例として基本クラスを使用してみましょう。

TMyClass = class
private
  FName: string;
  FID: Integer;
public
  constructor Create(AName: string);
  destructor Destroy; override; 
published
  property Name: string read FName write FName;
  property ID: Integer read FID write FID;
end;

field識別子とは、たとえばFNameandを意味FIDし、識別子とは、たとえばandpropertyを意味します。NameID

property私が間違っていなければ、公開された全体の目的は、クラスが書かれているユニットの外からアクセスできるようにすることです。これは確かにfield、クラスが記述されている単位で識別子を使用する必要があることを意味します。結局のところfield、クラスの外部でこれらの識別子にアクセスすることはできません。

FNameここで、一部の手順 (プライベートまたはプロテクト) でorを使用していないことに気付きましたFIDが、代わりにproperty同等のNameand ID- または混合を使用しています。

これまでのところ問題は見られませんでした。実際、通常は and を使用FNameしてFIDいましたが、私が言うように、何らかの理由でうっかり使用していませんでした。

これは悪い習慣ですか、それとももっと不吉なことにつながる可能性がありますか?

ありがとう。

4

1 に答える 1

6

プロパティの目的は、クラス自体の外部にあるクラス データへのアクセスを許可することではありません。
これは、メンバー データをパブリックとして宣言することで簡単に実行できます。

プロパティの目的は、適切な OOP を促進することです。
次の点は、概念を示しています。

副作用
プロパティの主な目的は、クラスの実装の詳細を隠し、プロパティを設定するときに「副作用」を許容することです。これは、SetHeight セッターでコード化された副作用により
、プロパティを変更するとウィンドウの外観が自動的に変更される VCL で明らかです。これは、情報隠蔽 の OOP 概念の一部です。height

これらの副作用は、クラス内にいるかどうかに関係なく役立ちます。
もう 1 つの便利な側面は、クラスまたはその子孫の 1 つがプロパティの動作を変更するときに発生します。以前にはなかった副作用を追加します。
元のクラス内の古いコードがフィールドを直接いじると、これらの副作用はトリガーされず、子孫内の変更が壊れます。

経験則: 副作用
明示的に副作用の発生を防ぎたい場合を除いて、常にこのプロパティを使用してください。!!ゲッターにも副作用があることを忘れないでください。

実装の隠蔽
フィールドが、プロパティ内の外観を直接翻訳していない場合があります。
または、ボンネットの下で実装を変更したいかもしれませんが、プロパティは同じに保ちます。
この場合も、子孫クラスが壊れないように、独自のクラスでもこれらの詳細を非表示にすることができます。
たとえば、ポインターを使用して赤/黒のツリーとしてストレージを実装している場合、配列ベースのオフセット構造に切り替えることを決定したときに、残りのルーチンへの影響を最小限に抑える必要があります。

経験則: 実装の隠蔽
データを直接扱うこれらのルーチンでは、フィールドに直接アクセスするだけにしてください。
ロケーター、イテレーターなどの汎用ルーチンを配置して、これらのルーチンの数を制限します。

于 2013-09-27T23:12:14.567 に答える