web-dev-qa-db-ja.com

パラメータを渡すタイミングとインスタンス変数を使用するタイミング

何かをローカルで追跡し、それを呼び出すすべてのメソッドに渡すか、インスタンス変数を宣言してメソッドで使用するかをどのように決定しますか?

クラスの最後のリストに保持されるインスタンス変数を好む傾向があります。しかし、私のプログラムがますます複雑になるにつれて、このリストはますます長くなります...何かが頻繁に渡されると、それを必要とするすべての男の子と女の子に見えるはずですが、私は疑問に思い始めます、 「なぜすべてを公開するのではないのでしょうか。そうすれば、何も渡す必要がなくなります!」

83
Ziggy

インスタンス変数を参照しているので、オブジェクト指向言語で作業していると想定しています。ある程度、インスタンス変数を使用する場合、スコープを定義する方法、ローカル変数を使用する場合は主観的ですが、クラスを作成するときはいつでも従うことができるいくつかの経験則があります。

  • インスタンス変数は通常、クラスの属性と見なされます。これらは、クラスから作成されるオブジェクトの形容詞と考えてください。インスタンスデータを使用してオブジェクトの説明に役立てることができる場合は、おそらくインスタンスデータに適した選択肢であることに間違いはありません。

  • ローカル変数はメソッドのスコープ内で使用され、作業の完了を支援します。通常、メソッドにはデータの取得、データの返還、および/または一部のアルゴリズムの処理/実行の目的が必要です。データ。場合によっては、ローカル変数を、メソッドが最初から最後まで取得できるようにする方法と考えると役立ちます。

  • インスタンス変数のスコープはセキュリティのためだけでなく、カプセル化のためにもあります。「すべての変数をプライベートに保つことを目標とすべきだ」と想定しないでください。継承の場合、通常、変数を保護されたものにするのが適切な代替手段です。すべてのインスタンスデータをパブリックとしてマークするのではなく、外の世界にアクセスする必要があるもののゲッター/セッターを作成します。それらすべてを利用可能にしないでください-必要なもののみ。これは、開発ライフサイクル全体を通じて行われます-始めから推測するのは困難です。

クラスの周りにデータを渡すことになると、コードを見ずにあなたがやっていることを良い習慣と言うのは難しいです。インスタンスデータを直接操作するのが適切な場合もあります。それ以外の場合はそうではありません。私の意見では、これは経験によってもたらされるものです。オブジェクト指向の思考スキルが向上するにつれて、直感を身に付けることができます。

47
Tom

これは主に、変数に保存するデータの寿命に依存します。データが計算中にのみ使用される場合は、パラメーターとして渡します。データがオブジェクトのライフタイムにバインドされている場合、インスタンス変数を使用します。

変数のリストが長すぎる場合は、クラスの一部を新しいクラスにリファクタリングすることを検討するのがよいでしょう。

42
H-Man2

私の意見では、インスタンス変数は、データが呼び出し間で使用される場合にのみ必要です。

以下に例を示します。

myCircle = myDrawing.drawCircle(center, radius);

MyDrawingクラスのイメージングでは、15個のヘルパー関数を使用してmyCircleオブジェクトを作成します。これらの各関数には、中心と半径が必要です。これらは、myDrawingクラスのインスタンス変数として設定しないでください。それらは二度と必要とされないからです。

一方、myCircleクラスは、中心と半径の両方をインスタンス変数として保存する必要があります。

myCircle.move(newCenter);
myCircle.resize(newRadius);

MyCircleオブジェクトがこれらの新しい呼び出しが行われたときの半径と中心が何であるかを知るには、それらを必要とする関数に渡されるだけでなく、インスタンス変数として保存する必要があります。

したがって、基本的に、インスタンス変数はオブジェクトの「状態」を保存する方法です。オブジェクトの状態を知るために変数が必要ない場合、インスタンス変数であってはなりません。

そして、すべてを公開することに関して。現時点であなたの人生が楽になるかもしれません。しかし、それはあなたを悩ませるために戻ってきます。しないでください。

16
ng.mangine

私見では:

変数がインスタンスの状態の一部を形成する場合、インスタンス変数-classinstance HAS-A instancevariableである必要があります。

インスタンスのメソッドに繰り返し何かを渡すことに気付いた場合、または何かを見逃したり、どこかで悪い抽象化を行った場合に備えて、おそらくデザインを見てみると、インスタンス変数が多数あることがわかりました。

それが役に立てば幸い

4
brabster

もちろん、パブリック変数の大きなリストをクラスに保持するのは簡単です。しかし、直感的にさえ、これは進むべき道ではないと言うことができます。

各変数を使用する直前に定義します。変数が特定のメソッドの機能をサポートしている場合、メソッドのスコープ内でのみ使用してください。

セキュリティについても考えてください。パブリッククラス変数は、「外部」コードからの不要な変更の影響を受けやすくなっています。あなたの主な目標は、すべての変数を非公開にすることであり、そうでない変数には、そうする非常に正当な理由があるはずです。

パラメーターをすべてスタックに渡すことについて、これは非常に高速になります。経験則では、メソッドシグネチャをクリーンでエレガントに保つことです。同じデータを使用する多くのメソッドを見る場合、それがクラスメンバーになるのに十分重要であるかどうかを判断し、そうでない場合は、コードをリファクタリングしてより意味のあるものにします。

それは常識に要約します。それぞれの新しい変数を宣言する場所と理由、その機能を正確に考え、そこからどのスコープに入れるべきかを決定します。

3
Yuval Adam