web-dev-qa-db-ja.com

Javaメソッドの命名規則:ゲッターが多すぎます

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

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

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

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

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

次に例を示します。

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

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

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

39
Are Husby

私は個人的に使用しないでください可能な限りゲッターとセッターを使用します(つまり、Strutsのようにそれを必要とするフレームワークは使用しません)。

可能であれば不変オブジェクト(public finalフィールド)を書くことを好みます。それ以外の場合は、パブリックフィールドを使用します:ボイラープレートコードを減らします。より多くの生産性、より少ない副作用。 get/setの本来の理由はカプセル化(オブジェクトをできるだけ恥ずかしがり屋にする)ですが、実際、私はそれをあまり必要としません。

Effective Javaでは、Joshua Blochがこの説得力のある推奨を行っています:

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

同じ本の中で、彼はまた言っています(しかし、私はここで本全体をコピーしたくありません):

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

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

27

JavaBeansの命名規則 に由来します。

16
John Topley

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

9
cHao

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

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

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

6
Jesper

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

5
user223364

1つの理由は、それが Java Bean Spec の重要な部分であるということです。

5
b_erb

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

4
Vadim Fedorov

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

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

3
GreenieMeanie

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

与えられた豆:-

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

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

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

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

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

3
Tarski

IDE持つ価値のあるものは、プライベート変数のゲッターとセッターを生成し、必要がない場合はそれらを折りたたむことができる日と年齢に住んでいるときに、「取得」は重要ですそれらを読みます?

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

C#{get, set}表記はコード行を削減するため、わずかに優れていますが、それでもすべての変数に対して入力する厄介な「get」があります。

3
duffymo

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

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

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

名前が名詞のみで構成され、戻り値を持つメソッドは、副作用がなく、比較的安価であると見なすことができます。名前に動詞が含まれ、戻り値がないメソッドには、副作用があります。名前に動詞が含まれ、戻り値があるメソッドは、比較的高価であり、副作用がある可能性があります。

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

3
Are Husby

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

私はこの結論に少し同意しません。私はそれがその意味を失うとは言いません、それは広く使われているので、getプレフィックスを持つメソッドはあなたが期待することとほとんど同じことをするでしょう。

次の例の場合:

Time.isoFormattedDateString(Date date)

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

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

getIsoFormattedDateString(Date date)

私の意見では、プロパティは完全にドロップするよりもエレガントなソリューションです。

2

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

2
Petar Minchev

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

1
Dan Haywood

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

例えば_Java.util.Map_では、size()getSize()と呼ばれる可能性がありますが、keySet()notgetKeySet()と呼ばれます。 。

1
finnw

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

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

しかし、深刻な計算がある場合、それを「取得」と呼ぶべきではないと思います。多分「計算」か何か。

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

1
Jay

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

0
rahul jain

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

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

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

  • この式で、メソッドaccount()と変数accountをどれだけ簡単に区別できますか。

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


コードにゲッターが多すぎる理由は心配する必要があります!

  • クラスを小さなクラスに分けるか、
  • クラスのインターンを公開する必要はなく、できる限り非表示にする必要があるため、コードをより適切に非表示にするだけです。
0
Leni Kirilov

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

0
nickik

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

0
bragboy