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


39

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

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

編集:

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

OOPの角度をしばらく無視すると、私が念頭に置いていた特定のユースケースは次のようになりました(擬似コードを簡潔にするために参照によるパスを想定しています)

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

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


1
この値はどのように使用されますか?一定ですか?変わりますか?コンパイル間の変更の影響を受けますか?
-Oded

物事がすべて同じであると自動的に判断される場合、それは重要ではないと考える方が簡単です。x-1のような調整された(x)値を必要とする関数がある場合はどうでしょうか?
ジェフ14年

回答:


15

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

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


1
私は同意します-クラスの元の設計/目的は、それがメンバー変数であるか引数であるかをあなたに伝えるべきです。また、依存性注入角度について考える価値があります。
Martijn Verburg

14

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

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


10

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

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

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

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

このアンチパターンには名前があるべきだと思いますか?(ここにはリストされいません)


アンチパターンとはどういう意味ですか?
ヴァヒドガディリ

要するに、2つ(またはそれ以上)の関数呼び出し間でパラメーターを共有するだけのメンバー変数を持つために...
Betlista

1

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

常に一緒に渡される2つ以上のテンポラリがある場合、ほぼ確実に新しいクラスを抽出する必要があります。


1

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

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

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

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

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

シンボリックに参照できるように(例:)、BLRFL_DURATIONメソッドに追加の引数を追加する必要がないため、コードが読みやすくなり、メンテナンスが容易になります。


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.