オブジェクト メソッド内からオブジェクトのプロパティにアクセスするにはどうすればよいでしょうか?[閉まっている]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

質問

ゲッター/セッター メソッドではないオブジェクト メソッド内からオブジェクトのプロパティにアクセスする「純粋な」または「正しい」方法は何ですか?

オブジェクトの外部からは getter/setter を使用する必要があることはわかっていますが、内部からは次のようにします。

ジャバ:

String property = this.property;

PHP:

$property = $this->property;

それとも次のようにしますか?

ジャバ:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

私の Java が少し間違っている場合はご容赦ください。Java でプログラミングしてから 1 年になります...

編集:

人々は私がプライベートまたは保護された変数/プロパティのみについて話していると想定しているようです。私が OO を学んだとき、たとえそれがパブリックであっても、すべてのプロパティに対してゲッター/セッターを使用するように教えられました (実際、変数/プロパティを決してパブリックにしてはいけないと言われました)。なので、最初から間違った思い込みから出発しているかもしれません。この質問に答える人はおそらく、パブリック プロパティを持つべきで、それらにはゲッターやセッターは必要ないと言っているようですが、これは私が教えられたこと、そして私が話していたことに反しています。ただし、それについては議論する必要があるかもしれません。良い。それはおそらく別の質問に適したトピックですが...

役に立ちましたか?

解決

これには宗教的な戦争の可能性がありますが、ゲッター/セッターを使用している場合は、内部でも使用する必要があるように思えます。両方を使用すると、将来的にメンテナンスの問題が発生する可能性があります (例:誰かがセッターにコードを追加します ニーズ そのプロパティが設定されるたびに実行され、セッターが呼び出されずにプロパティが内部的に設定されます)。

他のヒント

個人的には、一貫性を保つことが重要だと感じています。ゲッターとセッターがある場合は、それらを使用してください。フィールドに直接アクセスするのは、アクセサーのオーバーヘッドが大きい場合だけです。コードが不必要に肥大化しているように感じるかもしれませんが、将来的には大きな問題を解決できることは確かです。古典的な例:

後で、そのフィールドの動作方法を変更したい場合があります。おそらく、オンザフライで計算する必要があるか、あるいはバッキング ストアに別のタイプを使用したいかもしれません。プロパティに直接アクセスしている場合、このような変更により、一度に大量のコードが壊れる可能性があります。

この意見が一致していることにかなり驚いています getters そしてセッターは素晴らしくて良いです。アレン・ホルブによる扇動的な記事をお勧めします。」ゲッターとセッターは悪です」。確かに、このタイトルは衝撃的なものですが、著者は正当な指摘をしています。

本質的に、あなたが持っているなら、 getters そして setters それぞれのプライベートフィールドをパブリックなものと同じようにすることになります。プライベート フィールドの型を、それを呼び出すすべてのクラスに波及効果なしに変更するのは非常に困難です。 getter.

さらに、厳密に OO の観点から見ると、オブジェクトは (できれば) 単一の責任に対応するメッセージ (メソッド) に応答する必要があります。大多数の getters そして setters 構成オブジェクトとしては意味がありません。Pen.dispenseInkOnto(Surface) 私にとってはそれよりも理にかなっています Pen.getColor().

また、ゲッターとセッターは、クラスのユーザーがオブジェクトにデータを要求し、計算を実行して、オブジェクトに他の値を設定することを奨励します (手続き型プログラミングとしてよく知られています)。最初に行おうとしていたことをオブジェクトに単純に指示する方がよいでしょう。としても知られています 情報の専門家 熟語。

ただし、ゲッターとセッターは、UI、永続化などのレイヤーの境界にある必要悪です。C++ のフレンド キーワード、Java のパッケージで保護されたアクセス、.NET の内部アクセス、および フレンドクラスパターン の可視性を減らすのに役立ちます getters そして必要な人だけにセッターを与えます。

物件の使い方によって異なります。たとえば、name プロパティを持つ Student オブジェクトがあるとします。まだ取得されていない場合は、Get メソッドを使用してデータベースから名前を取得できます。こうすることで、データベースへの不要な呼び出しを減らすことができます。

ここで、名前が呼び出された回数をカウントするプライベート整数カウンターがオブジェクト内にあるとします。無効なカウントが生成されるため、オブジェクト内から Get メソッドを使用しないことをお勧めします。

PHP は、マジックメソッドを含む、これを処理する無数の方法を提供します。 __get そして __set, 、しかし私は明示的なゲッターとセッターを好みます。その理由は次のとおりです。

  1. 検証はセッター (さらに言えばゲッター) に配置できます。
  2. インテリセンスは明示的なメソッドで動作します
  3. プロパティが読み取り専用、書き込み専用、読み取り/書き込みのいずれであっても問題ありません
  4. 仮想プロパティ (計算値) の取得は、通常のプロパティと同じように見えます。
  5. 実際にはどこにも定義されておらず、文書化されていないオブジェクト プロパティを簡単に設定できます。

ここで私は行き過ぎているでしょうか?

多分 ;)

別のアプローチは、プライベート/保護されたメソッドを利用して実際に取得 (キャッシュ/データベースなど) を実行し、カウントをインクリメントするそのパブリック ラッパーを利用することです。

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

そしてオブジェクト自体の中から:

PHP:

$name = $this->_getName();

こうすることで、その最初の引数を別の目的で使用することができます (たとえば、ここでキャッシュされたデータを使用するかどうかのフラグを送信するなど)。

ここで私は要点を見逃していると思われますが、なぜオブジェクトのプロパティにアクセスするためにオブジェクト内で getter を使用するのでしょうか?

これを結論として、ゲッターはゲッターを呼び出し、ゲッターはゲッターを呼び出す必要があります。

したがって、オブジェクトメソッド内でプロパティに直接アクセスすることは、特にそのオブジェクト内の別のメソッドを呼び出すこと(とにかくプロパティに直接アクセスしてそれを返すだけである)は、単なる無意味で無駄な作業であると考えます(または、質問を誤解しましたか) )。

「純粋主義」が「ほとんどのカプセル化」を意味する場合、通常はすべてのフィールドをプライベートとして宣言し、クラス自体内から this.field を使用しますが、サブクラスを含む他のすべてのクラスはゲッターを使用してインスタンスの状態にアクセスします。

オブジェクト内であってもアクセサーメソッドを使用する方が良いと思います。すぐに思いつくポイントは次のとおりです。

1) オブジェクトの外部で行われたアクセスとの一貫性を維持するために行う必要があります。

2) 場合によっては、これらのアクセサー メソッドはフィールドにアクセスするだけではありません。追加の処理を行っている可能性があります (まれですが)。この場合、フィールドに直接アクセスすると追加の処理が失われ、アクセス中に常にこの処理が実行されるとプログラムが異常終了する可能性があります。

純粋主義的な OO の方法は、両方を避けて、 デメテルの法則 を使用して 尋ねないで伝えてください アプローチ。

オブジェクトのプロパティの値を取得する代わりに、 密接なカップル 2 つのクラスでは、オブジェクトをパラメータとして使用します。

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

プロパティがネイティブタイプだった場合、例:int の場合は、アクセス メソッドを使用し、プログラミング ドメインではなく問題のドメインに名前を付けます。

  doSomethingWithProperty( this.daysPerWeek() ) ;

これらにより、カプセル化と事後条件または依存する不変式を維持できるようになります。セッター メソッドを使用して、前提条件や依存する不変式を維持することもできます。ただし、セッターに名前を付けるという罠にはまらず、イディオムを使用するときは、ハリウッドの原則に戻って名前を付けてください。

セッター/ゲッターを使用するとコードが読みやすくなることがわかりました。また、他のクラスがメソッドを使用するとき、およびプロパティに保存されるデータを変更した場合に与えられる制御も気に入っています。

パブリックまたは保護されたプロパティを持つプライベート フィールド。値へのアクセスはプロパティを介して行われ、メソッド内で複数回使用される場合はローカル変数にコピーされる必要があります。アプリケーションの残りの部分が完全に調整され、ロックアウトされ、関連付けられたプロパティを介して値にアクセスすることがボトルネックになっている場合にのみ、開始する必要があります (そして、そのようなことは決して起こらないと私は保証します)プロパティ以外のものをそのバッキング変数に直接触れさせることを検討してください。

設計時にはバッキング変数を確認することさえできないため、.NET 開発者は自動プロパティを使用してこれを強制できます。

プロパティを編集しない場合は、 get_property() 別のオブジェクト内の MySQLi オブジェクトなどの特別な場合を除き、 public メソッドを使用します。その場合は、プロパティを公開して、それを次のように参照します。 $obj->object_property.

オブジェクト内では、私にとっては常に $this->property です。

場合によります。これは何よりもスタイルの問題であり、厳密なルールはありません。

私は自動学習者なので間違っている可能性がありますが、Java クラスでパブリック プロパティを使用したことはありません。パブリック プロパティは常にプライベートまたは保護されているため、外部コードはゲッター/セッターによってアクセスする必要があります。メンテナンスや改造の目的に適しています。そしてクラス内のコードについては...getter メソッドが簡単な場合はプロパティを直接使用しますが、必要に応じてイベントを起動するコードを簡単に追加できるため、私は常に setter メソッドを使用します。

そうですね、C# 3.0 プロパティのデフォルト実装では、決定が自動的に行われるようです。(おそらくプライベート) プロパティ セッターを使用してプロパティを設定する必要があります。

私が個人的にプライベート メンバービハインドを使用するのは、初期化時やキャッシュ/遅延読み込みが関係する場合など、そうしないとオブジェクトが望ましくない状態に陥る場合だけです。

の答えが好きです クムカロー, 、しかし、最も正しいのは次の答えのようです。 グレッグ・ハールマン. 。最初からゲッター/セッターを使い始めた場合、またはゲッター/セッターの操作に慣れている場合は、常にゲッター/セッターを使用してください。

余談ですが、個人的には、ゲッター/セッターを使用すると、コードが読みやすくなり、後でデバッグしやすくなることがわかりました。

いくつかのコメントに記載されているように、すべき場合もあれば、すべきではない場合もあります。プライベート変数の優れた点は、何かを変更するときにその変数が使用されているすべての場所を確認できることです。ゲッター/セッターが必要なことを行う場合は、それを使用してください。関係ないならあなたが決めてください。

逆のケースとして、ゲッター/セッターを使用し、誰かがそのゲッター/セッターを変更した場合、ゲッターとセッターが内部で使用されているすべての場所を分析して、何か問題が発生していないかどうかを確認する必要があるということも考えられます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top