15

一般的なCustomerクラスやEmployeeクラスのように、ビジネスクラスを扱う場合、ゲッターとセッターのみを使用するのが良いですか、それともプロパティを使用するのが良いですか?

私は(自己学習のために)Delphiに翻訳しています。JavaブックからのいくつかのOOの例です。これらの例では、常にGetName()とSetName()があり、プロパティは使用されません。

これで、公開されたプロパティを使用してコンポーネントを作成する場合、プロパティを使用する非常に正当な理由があることがわかりますが、通常のクラスでは、どちらのアプローチが優れていますか?コードは、ゲッターとセッター(プロパティの読み取り/書き込みを行っているという事実を強調する)またはプロパティ(一見するとパラメーターのないメソッドと混同される可能性がある)で読みやすくなっていますか?

4

4 に答える 4

40

わお。プロパティには、「getterメソッドとsetterメソッドの単なるラッパー」よりもはるかに多くのものがあります。

プロパティは、クラスフィールドへの制御されたアクセスを防ぐための、エレガントでありながら強力な方法です。

フィールドへのアクセス

すでに述べたように、クラスフィールドに直接アクセスできます。これは確かに非常に素晴らしく、コードをより明確にします。これは、クラスの実行可能な最初のバージョンを実装するための非常に優れた方法でもあります。

TMyClass = class
private
  FValue: String;
public
  property Value: String read FValue write FValue;
end; 

後で、クラスを再設計して、メソッドを使用してフィールドアクセスを検証および操作できます。パブリックインターフェイスは引き続き同じです。

TMyClass = class
private
  FValue: String;
  procedure SetValue(AValue: String);
public
  property Value: String read FValue write SetValue;
end; 

procedure TMyClass.SetValue(AValue: String);
begin
  if AValue = '' 
  then FValue := 'No value!'
  else FValue := AValue;
end;

アクセスの制御

プロパティを使用すると、読み取り専用/書き込み専用フィールドの概要を簡単に確認できます。例:読み取り専用/不変クラス:

TClient = class
private
  FName: String;
  FSite: String;
  FMail: String;
public
  constructor Create(AName, ASite, AMail: String);
  property Name: String read FName;
  property Site: String read FSite;
  property Mail: String read FMail;
end; 

ポリモーフィズム

TClient = class
private
  FName: String;
protected
  function GetName: String; virtual; abstract;
public
  property Name: String read GetName write FName;
end; 

TImportantClient = class(TClient)
protected
  function GetName: String; override;
end; 

TArgumentativeClient = class(TClient)
protected
  function GetName: String; override; 
end; 

function TImportantClient.GetName: String; 
begin
  Result := '+++ ' + FName;
end; 

function TArgumentativeClient.GetName: String; 
begin
  Result := ':-( ' + FName;
end; 

{----- ----- ----- ----- -----}
var
  ClientA,
  ClientB: TClient;
begin
  ClientA := TImportantClient.Create;
  ClientB := TArgumentativeClient.Create;

  ClientA.Name := 'Mr. Nice';
  ClientB.Name := 'Mr. Dumbhead';

  ShowMessage(ClientA.Name);
  ShowMessage(ClientB.Name);
end;
{----- ----- ----- ----- -----}

デフォルトのプロパティ

クラスでは、デフォルトのクラスフィールドを定義できます。これは、プロパティ名を指定せずにフィールドに直接アクセスできることを意味します。

A := MyStringList[i]:
MyStringList[i] := B;

{ instead of }

A := MyStringList.Strings[i];
MyStringList.Strings[i] := B;

{ or }

A := MyStringList.GetString(i);
MyStringList.SetString(i, B);

索引

キーワードを使用するIndexと、Delphiはgetter/setterメソッドに引数として定数値を渡します。

TMyRect = class
private
  FValues: Array[0..3] of Integer;
  function GetProperty(Index: Integer): Integer;
public
  property Top    : Integer  Index 0  read GetProperty;
  property Left   : Integer  Index 1  read GetProperty;
  property Width  : Integer  Index 2  read GetProperty;
  property Height : Integer  Index 3  read GetProperty;
end;


function TMyRect.GetProperty(Index: Integer): Integer;
begin
  Result := FValues[Index];
end; 

いくつかのリソース

カバーするトピックはまだいくつかあります(インターフェイスの実装、保存された値、RTTI /設計時のプロパティなど)が、この投稿は少し長くなり始めました...

これらのサイトで詳細を読むことができます:

于 2010-10-19T13:05:46.887 に答える
14

いいえ。ゲッターとセッターは、プロパティがないため、Javaにのみ存在します。これにより、プロパティを使用するためのよりクリーンなコードが作成されます。そして、ゲッターまたはセッターが必要な場合は、それをプロパティに組み込むことができますが、アクセスするコードに一連の関数呼び出しを散らかす必要はありません。

于 2010-10-18T22:36:09.053 に答える
10

プロパティはDelphiの大きな利点です。私は自分でかなりのJavaとDelphiを実行しており、間違いなくプロパティを選択します。実際には、どちらのアプローチも最終的には同じことを行いますが、プロパティがゲッター/セッターよりもはるかにきれいに見えるという唯一の違いがあります。

プロパティを利用して、それらを最大限に活用することをお勧めします。

于 2010-10-18T22:35:13.097 に答える
4

それは本当に味と使用の問題です。

パスカルのようなプログラマーの場合、値を読み書きしているかどうかは非常に明確です。したがって、Javaのような方法でゲッターとセッターを使用しないとコードが読みやすくなると思います。あなたのプログラム。

私にとって、そして大多数のパスカルプログラマーにとって、読み取り/書き込みしているプロパティの名前を入力するだけでコードが読みやすくなり、GetterまたはSetterメソッドが呼び出されることは誰もが知っています(必要な場合) 。

また、フィールドから直接プロパティ値を取得/設定できることは、delphiプロパティモデルの大きなメリット(およびエレガンス)だと思います。値がフィールドに割り当てられたり、フィールドから読み取られたりすることは、労力/時間の無駄です。

于 2010-10-18T22:42:08.217 に答える