35

次のものがあるとします

Class A {
    Foo getFoo();
    Bar getBar();
    Baz getBaz();
}

そして、 1 つのオブジェクトの、、をdoStuff使用して何らかの処理を行う関数を定義する必要があります。FooBarBaz

どちらの実装方法が優れているかで苦労しています( class 内doStuffに配置するのは望ましくないと仮定します)doStuffA

方法 A

void doStuff(Foo foo, Bar bar, Baz baz)
{ 
    //some operation
}

また

方法 B

void doStuff(A a)
{
    Foo foo = a.getFoo();
    Bar bar = a.getBar();
    Baz baz = a.getBaz();
    //some operation
}

私の限られた知識では、(+長所、-短所)

方法 A

+どのパラメータdoStuff()が動作するかが正確に明確です

- 長いパラメーター リストに影響を受けやすく、ユーザーのミスが発生しやすい

方法 B

+シンプルで使いやすい方法

+より拡張可能に見える (?)

-クラスに対する不要な依存関係を作成しますA


これら 2 つの方法の長所と短所について、追加の洞察を共有できる人はいますか?

4

4 に答える 4

45

メソッド A (ネイキッド パラメーター) には常に次のような利点があります。

  • パラメータオブジェクトを実装する必要がないため、メソッドの作成者は型を少なくする必要があります。
  • パラメータオブジェクトをインスタンス化する必要がないため、メソッドの呼び出し元が型を少なくする必要があります。
  • パラメータオブジェクトを構築してガベージコレクションする必要がないため、パフォーマンスが向上します
  • 読者は、メソッド シグネチャだけから個々のパラメータが何であるかを確認できます (ただし、これは諸刃の剣です。以下を参照してください)。

メソッド B (パラメータ オブジェクト) には次のような利点があります。

  • パラメータにはグループとしてドメインの意味があるため、パラメータ オブジェクトにはその意味を説明する名前を付けることができ、読者はグループの各メンバーとそれらがどのように関連しているかを読んで理解する必要がなくなります。
  • パラメーター リストは複数のメソッドで使用されるため、各メソッドでパラメーター オブジェクトを使用すると、重複を減らすことができます。
  • パラメーター リストの値は、複数のメソッド間でグループとして渡されます。これは、単一のパラメーター オブジェクトとして渡すことができると簡単です。
  • 一部の値の組み合わせは無効です。パラメータオブジェクトはそれらの組み合わせを防ぐことができます
  • 一部の値はオプションであり、(言語によっては) デフォルトのパラメーター値またはオーバーロードされたメソッドの代わりに、パラメーター オブジェクトによって提供できます。
  • 同じ型のパラメーターが複数あるため、値の交換エラーが発生しやすくなります (ただし、この場合、メソッドと同じパラメーター リストを持つコンストラクターがある場合、パラメーター オブジェクトは適切ではありません)。

Parameter Object が呼び出し元と呼び出し先が依存する新しい依存関係を導入することは、それ自体の依存関係を持たない単純なクラスであるため、それほど不利ではありません。

したがって、パラメータオブジェクトは

  • 単一のパラメーターにはほとんど価値がなく、2 つのパラメーターのメソッド (たとえば、Point は通常 x、y よりも優れている) には価値がある場合もあれば、そうでない場合もあり、3 つ以上のパラメーターではますます役に立ちます。
  • より多くのメソッドが同じパラメーター リストを使用する場合、ますます役立ちます
于 2016-04-28T04:43:08.950 に答える
7

Parameter Objectrelateds は、パラメーターをカプセル化して、メソッドまたはコンストラクターの合計パラメーター数を減らすための優れたアプローチを提供します。パラメータ オブジェクトに実際に関連するパラメータが実際に含まれていることを確認するには、細心の注意を払う必要があります。

parameter types実際には、扱っているものに応じて、この問題にアプローチする方法が複数あります。String複数の やのような一般的なタイプのパラメーターを扱っていて、クライアントが実際に間違った引数のシーケンスを渡す可能性がある場合は、多くの場合、 ieIntを作成する方が理にかなっています。custom types可能な値で作成enumします。これにより、引数のコンパイル時チェックを適切に行うことができます。それらの別の良い使い方は、それらをreturn関数からの複雑な値に使用できることです。ここを参照してください。

doStuff私がよく行うもう 1 つのアプローチは、メソッドによって行われた作業が依存関係の少ない単純なメソッドに分割されているかどうかを確認することです。

基本的に、最大 3 つのパラメーターという Bob Martin の推奨に従うようにしています。まあ、彼は実際には、それはほとんど1つ以下であるべきだと言っています! 増加には正当な理由が必要です。この優れた本を参照してください:Clean Code

于 2016-04-28T07:41:21.830 に答える