web-dev-qa-db-ja.com

クラスメンバーを優先するか、内部メソッド間で引数を渡すか?

クラスのプライベート部分内に、複数のプライベートメソッドで使用される値があるとします。人々はこれをクラスのメンバー変数として定義することを好むか、またはそれを各メソッドへの引数として渡すことを好みますか?そしてなぜですか?

一方では、クラスの状態(つまり、メンバー変数)を減らすことは一般的に良いことであるという主張をすることができますが、クラスのメソッド全体で同じ値が繰り返し使用されている場合、それは理想的なようですクラスの状態としての表現の候補。

編集:

提起されたコメント/質問のいくつかを明確にするために、私は定数について話しているのではなく、これは特定のケースに関連しているのではなく、私が他の人に話している仮説に関連していません。

OOP角度を少しの間無視して、私が頭に浮かんだ特定のユースケースは次のとおりです(疑似コードをよりクリーンにするために参照渡しすることを想定しています)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

つまり、複数の関数に共通する変数がいくつかあるということです。私が念頭に置いていた場合、それは、より小さな関数の連鎖によるものでした。 OOPシステムでは、これらがクラスのすべてのメソッドである場合(たとえば、大きなメソッドからメソッドを抽出することによるリファクタリングが原因)、その変数はそれらすべてに渡されるか、クラスである可能性がありますメンバー。

45
geoffjentry

値がクラスのプロパティである場合は、クラスに保持します。それ以外の場合は、外に保管してください。最初にクラスメソッドを設計することはありません。最初にそのプロパティを設計します。そもそもそのプロパティをクラス内に置くことを考えていなかったのなら、おそらくそれには理由があります。

スケーラビリティの観点からできる最も悪いことは、便宜上コードを変更することです。遅かれ早かれ、コードが肥大化して複製されることに気づくでしょう。しかし、私は認めなければなりません。時々、私はこのルールを破ります。利便性はとてもすごく魅力的です。

17
AJC

呼び出し間で実際に状態を保持する必要がない場合(そして、どうしても必要ない場合、または質問しない場合)、値はメンバー変数ではなく引数にすることをお勧めします。メソッドのシグネチャで、引数を使用することがわかりますが、メソッドで使用されているメンバー変数をすぐに特定するのは少し難しいです。また、プライベートメンバー変数が何のためにあるのかを判断するのが常に速いとは限りません。

そのため、通常、メンバー変数を使用するコードが明らかにクリーンであることに同意しませんが、メソッドシグネチャが手に負えなくなった場合は、例外を作成する可能性があります。これは価値のある質問ですが、プロジェクトがいずれにせよ依存するものでもありません。

14
psr

質問してくれてありがとう、これも聞きたかった。

私がこれについて考えていたとき、それを引数として渡す理由にはいくつかの利点があります

  • テストが簡単->メンテナンスが簡単(最後のポイントに関連)
  • 副作用はありません
  • 理解しやすい

たとえば、あなたのポイントははっきりとわかります-1つは(たとえばPOIライブラリーを使用して)E​​xcelドキュメントを解析し、その行を処理する必要があるすべてのメソッドに行インスタンスを渡す代わりに、作成者にはメンバー変数currentRowがあり、それ。

このアンチパターンには名前があるべきだと思いますよね? (リストされていない ここ

10
Betlista

おそらく、その値を共有するすべてのメソッドを含む新しいクラスを抽出する必要があります。もちろん、最高レベルのメソッドは新しいクラスで公開されます。テストのためにそのメソッドを公開すると役立つ場合があります。

常に一緒に渡される2つ以上の一時ファイルがある場合は、ほぼ確実に新しいクラスを抽出する必要があります。

1
kevin cline

人々はこれをクラスのメンバー変数として定義することを好むか、またはそれを各メソッドへの引数として渡すことを好みますか?そしてなぜですか?

私があなたが求めていることを理解している場合:クラス内のメソッドは、定義により実装の詳細に関係するので、任意のメソッドから任意のメンバーを直接使用することに不安はありません。

一方では、クラスの状態(つまり、メンバー変数)を減らすことは一般に良いことであるという議論を見ることができました...

定数を定義するためにprivate static finalを宣言しても問題はありません。コンパイラーは、いくつかの最適化を検討する際に値を使用でき、定数であるため、実際にはクラスに状態を追加しません。

ただし、クラスのメソッド全体で同じ値が繰り返し使用されている場合...

記号で参照できるようにすることで(例:BLRFL_DURATION)、メソッドに引数を追加する必要がないため、コードが読みやすくなり、保守が容易になります。

1
Blrfl

値が変わらない場合は、定義により定数であり、クラス内にカプセル化する必要があります。このような場合、オブジェクトの状態に影響を与えるとは見なされません。あなたのケースはわかりませんが、三角法のPIなどのことを考えています。このような定数の引数を渡そうとすると、クライアントが間違った値またはメソッドが期待するものと同じ精度でない値を渡した場合、結果がエラーにさらされる可能性があります。

0
NoChance