メソッドに引数を渡すか、オブジェクトのすべてのメソッドから見えるオブジェクトインスタンス変数として単に引数を宣言するかをどのように決定しますか?
クラスの最後のリストにインスタンス変数を保持することを好みますが、このリストは私のプログラムが大きくなるにつれて長くなります。変数が十分に頻繁に渡されるかどうかは、それを必要とするすべてのメソッドから見えるようにする必要がありますが、「すべてが公開されている場合は、何も渡す必要がまったくありません!」
回答:
インスタンス変数を参照しているので、私はあなたがオブジェクト指向言語で作業していると想定しています。インスタンス変数をいつ使用するか、そのスコープを定義する方法、およびローカル変数をいつ使用するかはある程度主観的ですが、クラスを作成するときは常に従うことができるいくつかの経験則があります。
インスタンス変数は通常、クラスの属性と見なされます。これらは、クラスから作成されるオブジェクトの形容詞と考えてください。インスタンスデータを使用してオブジェクトの説明に役立てることができる場合は、インスタンスデータに適していると考えるのが無難でしょう。
ローカル変数は、メソッドのスコープ内で使用され、作業を完了できるようにします。通常、メソッドには、一部のデータを取得する、一部のデータを返す、および/または一部のデータに対してアルゴリズムを処理/実行するという目的があります。場合によっては、ローカル変数をメソッドを最初から最後まで支援する方法として考えると役立ちます。
インスタンス変数のスコープは、セキュリティのためだけでなく、カプセル化のためにもあります。「すべての変数をプライベートに保つことが目標である」と想定しないでください。継承の場合、通常、変数を保護されたものにすることは良い選択肢です。すべてのインスタンスデータを公開するのではなく、外部にアクセスする必要のあるインスタンスのゲッター/セッターを作成します。それらすべてを利用可能にするのではなく、必要なものだけを利用してください。これは、開発ライフサイクル全体を通じて行われます-最初から推測するのは困難です。
クラスの周りでデータを渡すことになると、コードを確認せずに、何をしているのかを判断するのは困難です。場合によっては、インスタンスデータを直接操作しても問題ありません。それ以外の場合は、そうではありません。私の意見では、これは経験に伴うものです。オブジェクト指向の思考スキルが向上するにつれて、いくつかの直感が発達します。
私の意見では、インスタンス変数は、データが呼び出し間で使用される場合にのみ必要です。
次に例を示します。
myCircle = myDrawing.drawCircle(center, radius);
ここで、myDrawingクラスのイメージングで15のヘルパー関数を使用してmyCircleオブジェクトを作成します。これらの各関数には中心と半径が必要です。それでも、myDrawingクラスのインスタンス変数として設定しないでください。それらが再び必要になることは決してないからです。
一方、myCircleクラスは、インスタンス変数として中心と半径の両方を格納する必要があります。
myCircle.move(newCenter);
myCircle.resize(newRadius);
これらの新しい呼び出しが行われたときにmyCircleオブジェクトが半径と中心を認識するためには、それらを必要とする関数に渡すだけでなく、インスタンス変数として保存する必要があります。
したがって、基本的に、インスタンス変数はオブジェクトの「状態」を保存する方法です。変数がオブジェクトの状態を知る必要がない場合は、インスタンス変数であってはなりません。
そしてすべてを公開することに関しては。それはあなたの人生を一瞬で楽にするかもしれません。しかし、それはあなたを悩ませるために戻ってきます。やめてください。
もちろん、クラスにパブリック変数の大きなリストを1つ保持するのは簡単です。しかし、直感的にも、これは進むべき道ではないことがわかります。
使用する直前に各変数を定義します。変数が特定のメソッドの機能をサポートする場合は、メソッドのスコープ内でのみ使用してください。
セキュリティについても考慮してください。パブリッククラス変数は、「外部」コードからの不要な変更の影響を受けやすくなっています。あなたの主な目標は、すべての変数をプライベートに保つことであり、そうでない変数は、プライベートであることに十分な理由があるはずです。
スタック全体に渡るパラメーターの受け渡しについては、これは非常に速く醜くなります。経験則では、メソッドシグネチャをクリーンでエレガントに保つことです。同じデータを使用する多くのメソッドが表示される場合は、クラスメンバーであることが重要であるかどうかを判断し、そうでない場合は、コードをリファクタリングしてより意味のあるものにします。
それは、常識に要約されます。それぞれの新しい変数を宣言する場所と理由を正確に考え、関数はどうあるべきかを考え、そこから、変数をどのスコープに含めるかを決定します。