104

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

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

ジャワ:

String property = this.property;

PHP:

$property = $this->property;

またはあなたはしますか:

ジャワ:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Java でプログラミングを始めてから 1 年が経ちましたが、私の Java が少しずれていたらすみません。

編集:

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

4

18 に答える 18

65

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

于 2008-08-01T16:13:47.600 に答える
44

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

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

于 2008-08-01T18:23:59.040 に答える
27

私はgetters、セッターが元気で良いという意見がいかに満場一致であるかにかなり驚いています. Allen Holub の扇動的な記事「Getters And Setters Are Evil」をお勧めします。確かに、タイトルはショック値のためですが、著者は有効な点を指摘しています.

基本的に、すべてのプライベート フィールドがある場合は、それらのフィールドをパブリックと同じように作成しますgetterssettersそれを呼び出すすべてのクラスに波及効果なしにプライベート フィールドの型を変更するのは非常に難しいでしょうgetter

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

また、ゲッターとセッターは、クラスのユーザーがオブジェクトにデータを要求し、計算を実行してから、オブジェクトに他の値を設定することを奨励します。これは手続き型プログラミングとしてよく知られています。最初にやろうとしていたことをオブジェクトに単純に指示する方がよいでしょう。Information Expertのイディオムとしても知られています。

ただし、ゲッターとセッターは、レイヤーの境界 (UI、永続性など) では必要悪です。C++ のフレンド キーワード、Java のパッケージ保護アクセス、.NET の内部アクセス、フレンド クラス パターンgettersなど、クラスの内部へのアクセスを制限することで、セッターとセッターの可視性をそれらを必要とする人だけに減らすことができます。

于 2008-09-19T00:13:34.160 に答える
20

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

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

于 2008-08-01T16:19:04.283 に答える
15

PHP には、マジック メソッド__getや など__set、これを処理する方法が無数にありますが、私は明示的なゲッターとセッターを好みます。理由は次のとおりです。

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

私はここで船外に出ていますか?

多分 ;)

別のアプローチは、プライベート/保護されたメソッドを使用して実際に取得 (caching/db/etc) を行い、カウントをインクリメントするパブリック ラッパーを使用することです。

PHP:

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

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

次に、オブジェクト自体から:

PHP:

$name = $this->_getName();

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

于 2008-08-01T16:43:30.880 に答える
13

ここで要点を見逃しているに違いありません。オブジェクト内でゲッターを使用して、そのオブジェクトのプロパティにアクセスするのはなぜですか?

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

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

于 2011-06-04T15:42:09.807 に答える
9

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

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

  2. 場合によっては、これらのアクセサ メソッドがフィールドへのアクセス以上のことを行っている可能性があります。追加の処理を行っている可能性があります (ただし、これはまれです)。この場合、フィールドに直接アクセスすると、追加の処理が行われないことになり、アクセス中に常にこの処理が行われると、プログラムがうまくいかなくなる可能性があります。

于 2010-01-20T08:32:59.530 に答える
9

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

于 2008-08-22T11:15:45.690 に答える
9

この質問は、意見に基づく回答を必要としません。これは、高凝集性、低結合の原理、およびSOLIDの原理から、数十年にわたってコンピューティング サイエンスによって十分にカバーされている主題です。

純粋で正しく読めるオブジェクト指向の方法は、カップリングを最小限に抑え、結束を最大化することです。したがって、どちらも避けるべきであり、Demeter の法則に従って、Tell Don't Askアプローチを使用する必要があります。

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

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

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

  doSomethingWithProperty( this.daysPerWeek() ) ;

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

于 2008-09-24T17:04:35.240 に答える
8

セッター/ゲッターを使用すると、コードが読みやすくなることがわかりました。また、他のクラスがメソッドを使用するときに提供されるコントロールが気に入っています。データを変更すると、プロパティに格納されます。

于 2008-08-18T17:37:01.130 に答える
8

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

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

于 2008-08-18T17:43:29.323 に答える
8

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

オブジェクト内では常に $this->property です。

于 2008-08-22T11:34:06.987 に答える
8

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

于 2008-08-06T14:43:54.830 に答える
8

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

于 2008-10-01T10:51:49.700 に答える
6

C# 3.0 のプロパティの既定の実装では、決定はユーザーに委ねられているようです。(おそらくプライベートな)プロパティセッターを使用してプロパティを設定する必要があります。

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

于 2008-08-01T16:56:55.830 に答える
6

私はcmccullohによる答えが好きですが、最も正しいのはGreg Hurlmanによる答えのようです。getter/setter を最初から使用し始めた場合、および/または使用に慣れている場合は、常に getter/setter を使用してください。

余談ですが、ゲッター/セッターを使用すると、コードが読みやすくなり、後でデバッグしやすくなります。

于 2008-09-15T09:46:13.973 に答える
5

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

逆に、ゲッター/セッターを使用していて、誰かがゲッター/セッターを変更した場合、ゲッターとセッターが内部で使用されているすべての場所を分析して、何か問題があるかどうかを確認する必要があります。

于 2008-08-01T17:01:27.240 に答える