40

Javaメソッド名が「get」プレフィックスを非常に広範囲に使用するのはなぜですか?少なくとも私のJavaプログラムには、「get」という単語で始まる名前のメソッドがたくさんあります。get-methodsの割合が疑わしいほど高くなっています。インフレのせいで「ゲット」という言葉の意味がなくなってきていると感じ始めています。私のコードではノイズです。

機能/宣言型プログラミングとPL/SQLで使用されている命名規則が異なることに気づきました。メソッド名は、メソッドが返すものを単に示しています。account.getAmount()またはの代わりに、およびTime.getIsoFormattedDateString(Date date)を使用account.amount()Time.isoFormattedDateString(Date date)ます。関数の名前はメソッドを評価した結果を表すので、これは私には完全に理にかなっています(とにかくあるべきではない副作用がないと仮定します)。「get」プレフィックスは不要のようです。

「クリーンコード」という本を読み始めたところです。メソッドは1つのことだけを実行する必要があり、そのことは通常、次のいずれかである必要があると書かれています。

  1. イベントについてオブジェクトに通知します。通常は、イベントをパラメータとして渡します。
  2. あるオブジェクトについて質問します。通常、メソッド名は自然言語ステートメントを形成し、オブジェクトをパラメーターとして渡し、ブール値を返します。
  3. 何かをフェッチし、場合によってはルックアップキーまたは変換対象のオブジェクトをパラメータとして渡し、常に目的のオブジェクト/値を返します。

私の質問は3番目のカテゴリーについてです。この種のメソッドには、「get」以外の命名規則がありますか?メソッド名/プレフィックスを選択するときにどのような基準を使用しますか?

次に例を示します。

getDates()2つのメソッドと。を持つクラスがありgetSpecialDates()ます。getDates()プライベート変数の値(日付のコレクションへの参照)を返すだけです。私が理解しているように、これは標準的なゲッターです。getSpecialDates()異なります; を呼び出しgetDates()、別のクラスからフィルターをフェッチし、フィルターを適用して、実質的にのサブセットであるものを返しますgetDates()

getSpecialDates()メソッドには、、、などの名前computeSpecialDates()を付けることができます。または、単に名前を付けることもできます。そして、一貫性を保つために、名前をに変更できます。findSpecialDates()selectSpecialDates()elicitSpecialDates()specialDates()getDates()dates()

接頭辞が「get」である必要があるメソッドとそうでないメソッドをわざわざ区別するのはなぜですか。また、「get」の代わりの単語をわざわざ見つけるのはなぜですか。

4

20 に答える 20

27

個人的には、可能な限りゲッターとセッターを使用しません(つまり、たとえば Struts など、ゲッターとセッターを必要とするフレームワークは使用しません)。

可能であれば、不変オブジェクト ( public finalフィールド)を書くことを好みます。それ以外の場合は、 public フィールドのみを使用します。定型コードが少なくなり、生産性が向上し、副作用が少なくなります。get/set の元の正当化はカプセル化 (オブジェクトを可能な限りシャイにする) ですが、実際、私はそれを頻繁に必要とするわけではありません。

Joshua Bloch は、Effective Java で次の説得力のある推奨事項を述べています

クラスを可変にする非常に正当な理由がない限り、クラスは不変でなければなりません...クラスを不変にできない場合は、その可変性を可能な限り制限してください。

同じ本の中で、彼は次のようにも述べています (ただし、ここで本全体をコピーしたくはありません)。

JavaBeans パターンには重大な欠点があります。

JavaBeans は当初、非常に狭い問題領域 (IDE でのグラフィカル コンポーネントの操作) を対象としていたため、私はこれに完全に同意します。別の問題を解決するために設計されたソリューションを使用することは、悪い習慣です。

于 2010-07-09T10:55:34.823 に答える
16

これは、 JavaBeans の命名規則に由来します。

于 2010-07-09T09:02:26.840 に答える
9

非常に多くの get* メソッドが存在する理由の 1 つは、Java が .net/COM のような「プロパティ」をサポートしていないことです。Java Bean などは、関数 getX および setX を使用して、X と呼ばれるプロパティの機能を複製します。 Java はこれを利用して、プロパティの設定と取得を可能にします。

于 2010-07-09T08:58:41.060 に答える
6

getterメソッドとsetterメソッドがJavaで記述されることが多い理由の1つは、JavaBeansの規則を使用しているためです。

ただし、標準のJava APIは、これに関して一貫性がありません。たとえば、クラスStringにはlength()メソッドがあり、インターフェイスはまたはの代わりにメソッドをCollection定義します。size()getLength()getSize()

Javaは統一アクセスの原則をサポートしていないため、プロパティにアクセスするにはgetterメソッドとsetterメソッドを作成する必要があります。

于 2010-07-09T09:05:53.340 に答える
6

getSpecialDates()computeSpecialDates()findSpecialDates()selectSpecialDates()などのメソッド名は、名前elicitSpecialDates()に動詞 (アクション) が使用されているため、私にとってはコマンドです。コマンドは、呼び出すたびに副作用を持つことを意図しています。date()dates()、 [名詞] などのメソッド名は、specialDates()副作用のない有用な値を返すメソッドです。メソッドを複数回呼び出すと、状態を変更する副作用を持つコマンドが呼び出されない限り、毎回同じ値が返されます。

于 2010-07-12T02:02:47.497 に答える
5

その理由の 1 つは、これがJava Bean 仕様の不可欠な部分であることです。

于 2010-07-09T09:01:26.997 に答える
4

Java開発者が一般的なget/set規則を使用する必要がある理由の1つは、多くのフレームワークがBeanの作成とフィールドの設定にこれに依存していることです。たとえば、Spring Beanのように設定されたプロパティがあり、クラスに名前が<property name="foo" value="bar" />付けられたメソッドがない場合setFoo()、Beanの作成時にエラーが発生します。

于 2010-07-09T09:07:34.100 に答える
4

前提 1: メソッドは 1 つのことだけを行う必要があります。前提 2: ゲッター メソッドは、get プレフィックスを使用するかどうかに関係なく、副作用があってはなりません。これらの 2 つの前提を考えると、私が提案するのは、何かをフェッチすることを役割とし、比較的単純で安価な方法でそれを行うメソッドは、その名前に動詞を含める必要がないということです。

ゲッターの存在理由は何かをすることではなく、何かを評価することです。メソッドが何をするかには興味がありませ。副作用がないため、メソッド内で行われる計算は重要ではありません。メソッドが返すものだけに関心があります。メソッド名は、それを名詞の形で反映する必要があります。名詞だけで構成されるメソッド名は、常に「ゲッター」にする必要があります。

接頭辞「get」の情報は、動詞がないことから推測できます。これは、get プレフィックスを使用するよりも単純で直感的です。

名前が名詞のみで戻り値を持つメソッドは、副作用がなく、比較的安価であると見なすことができます。名前に動詞が含まれ、戻り値を持たないメソッドは、副作用を持つために存在します。名前に動詞が含まれ、戻り値を持つメソッドは、比較的コストが高く、副作用があると見なすことができます。

誰もがあちこちで「get」と書いているのは、JavaBeans パターンに由来する独断的な伝統にすぎないようです。実際にそれを必要とするツール/フレームワークを使用する予定がある場合は、get プレフィックスを残しておいてください。

于 2010-07-13T09:54:15.320 に答える
3

個人的にはハマってgetます。それはまさに人間の言語です。あなたが何かをしたいとき、あなたは何かをしたいですgetgetプレフィックスに問題はありません。命名規則については、たとえばSelect、データベース クエリのプレフィックスが考えられます。SelectUsers

于 2010-07-09T08:58:03.487 に答える
3

IDE がプライベート変数の getter と setter を生成し、それらを読みたくない場合はそれらを折りたたむことができる時代に私たちが住んでいるときに、「get」は何を意味しますか?

あなたの本当の問題はデザインに関するものであるべきです:なぜあなたのオブジェクトはこれほど多くの属性を持っているのでしょうか? オブジェクトにゲッターとセッターしかない場合、「貧血ドメイン モデル」に悩まされていませんか?

C#{get, set}表記法は、コード行を削減できるため、わずかに優れていますが、変数ごとに入力する厄介な "get" がまだ残っています。

于 2010-07-09T11:24:53.880 に答える
3

他の人が述べたように、それは Java Beans 用です。ただし、Java を使用している場合は、メソッド getXXX() が値を返すだけで他に何もしない場合にのみ名前を付けてください。あなたが示唆したように、何か他のことをしている場合は、computeXXX() などの別の名前を付けます。

50 行のコードを含む getXXX() メソッドを見つけることがあります。この場合は、やり方が間違っています。

于 2010-07-09T19:24:02.947 に答える
3

多くの人がすでに述べているように、get..() と set()... は Java Beans Convention の一部です。これは、Java 仕様の他の部分との相互運用に必要です。たとえば、JSP では、getプレフィックスを付けずにプロパティ名を指定することで、Java からメンバーにアクセスできます。

与えられた豆:-

public class Foo {
  public int getX() { return 1; }
}

X を取得するには、次の JSP を実行できます。

<jsp:useBean id="aFoo" class="Foo" />
<c:out value="${aFoo.X}" />

この種のメソッドには「get」以外の命名規則はありますか?

はい、ブール値のプロパティisの代わりに使用できます。get

于 2010-07-09T09:58:23.923 に答える
2

インフレのせいで「ゲット」という言葉が意味を失っているように感じ始めています。私のコードではノイズです。

私はこの結論に少し反対します。その意味が失われるとは言いませんが、広く使用されているため、 get プレフィックスを持つメソッドは、期待どおりのことを行うと言えます。

次の例では:

Time.isoFormattedDateString(Date date)

これにより、入力パラメーターに基づいてフォーマット タイプが設定されるため、後続のすべての呼び出しでこのフォーマットが使用されますか?

静的メソッドであるため、誰かがその結論に達するのは少し無理が​​あることは承知していますが、このメソッドがインスタンスで呼び出されたかどうかを確認できますか? おそらくですが、 get を使用すると、すべてのあいまいさがなくなります。

getIsoFormattedDateString(Date date)

私の意見では、プロパティは get を完全に削除するよりも洗練されたソリューションです。

于 2010-07-09T09:52:01.513 に答える
1

履歴スニペット:非常に初期のJava 1.0 API(JavaBeansより前)のいくつかを見ると、それらに「get」プレフィックスがないことがわかります。たとえば、java.awt.Container#minimumSize()は非推奨になり、#getMinimumSize()に置き換えられました。

于 2010-07-09T10:05:57.150 に答える
1

1 つのオプションは、getプリミティブ値または不変値を返すメソッドのプレフィックスを保持し、元の受信者を変更するために使用できる参照を返すメソッドのプレフィックスを削除することです。

たとえば、 injava.util.Mapsize()呼び出すことはできますが、呼び出すことgetSize()はできkeySet()ませgetKeySet()

于 2010-07-13T10:30:18.893 に答える
1

これは、「変数と関数に意味のある名前を付ける」という理想のサブセットだと思います。

「get」には、多くの人が指摘しているように、Java Beans では特定の意味があります。したがって、おそらく副作用を伴い、内部変数の値を取得するために使用することに限定する必要があると思います。「取得」に、データ型の変換を行ったり、埋め込みクラスから値を抽出したり、「public int getRightMargin() { return width-margin.left; }」のように他の値を再解釈したりするなど、小さな計算が含まれる場合は許容できると思います。副作用は、取得されたことを示すフラグを設定するなど、値を取得することの真の「副作用」に限定する必要があります。

でも、本格的な計算なら「get」と呼ぶべきではないと思います。多分「calc」か何か。

関数の名前付けに使用する一貫した用語があるとよいでしょう。たとえば、"read" は主なアクティビティがデータベースから何かを取得することを意味し、"calc" は計算などを行うことを意味することに全員が同意した場合などです。しかし、それは非現実的かもしれません。微妙な違いがあるケースが多すぎるのかもしれません。

于 2010-07-09T15:22:46.487 に答える
0

そうですね、JavaBeansの仕様では、ゲッターとセッターを宣言するように求められていますが、絶対に必要な場合を除いて、通常は宣言しません(多くのMVCフレームワークの場合のように)。私はJavaのキャリアで多くのスイングを行い、変数をパブリックとして宣言する傾向があります(ええ、それは少し非OOPyに聞こえます)。しかし、それは簡潔に見え、「私は」自分が何をしているのかを知っているので、私はそれが好きでした。それが持っていた唯一の利点は、行数の削減です。

于 2010-07-09T09:05:22.777 に答える
0

get と set は、プロパティのみを取得または設定するメソッドに対してのみ使用し、それ以外は使用しません。

于 2010-07-09T09:01:58.353 に答える
0

Java Beans はその命名規則に非常に固執します。たとえば、変数名 Name を宣言し、対応するセッターを setName() として宣言するとします。ただし、setName は Name ではなく「name」に対応している必要があるため、エラーが発生します。別のブール値の例 isReadey; getter isReady() を使用します。ブール値の準備ができているかどうかを確認すると、再びエラーが発生します。そのため、コードを作成する前に、この命名規則に精通している必要があります。しかし、私は個人的にこの慣習を好みます。なぜなら、プログラマーの作業が簡単になり、少し時間を費やした後は少し論理的であるように思われるからです。

于 2010-07-09T09:26:00.880 に答える
-1

次の理由から、「get」プレフィックスを残すことが重要です。

  • メソッドはアクションを記述する必要があるため、名前に動詞を含める必要があります

  • get は、変数の状態が変わらないことを示しています

  • account()この式でメソッドと変数をどのくらい簡単に区別できますかaccount:

    newAccount = currentAccount + account()--- これは何をしaccount()ますか?


コードに getter が多すぎる理由を心配する必要があります。

  • クラスを小さなクラスに分けるか、
  • クラスのインターンを明らかにする必要はなく、できる限り隠そうとする必要があるため、コードをより適切に非表示にします。
于 2010-07-09T12:11:06.060 に答える