10

私は一貫性、ひいては慣習を大いに信じています。

ただし、私は現在Javaでフレームワークを開発しており、これらの規則(具体的にはget/setプレフィックス規則)が読みやすさの妨げになっているようです。たとえば、一部のクラスにはプロパティがあり、代わりにを使用idすることは、いくつかの理由でまったく無意味に思えます。nameo.getId()o.id()

  • クラスは不変であるため、(一般的に)対応するセッターはありません。
  • 混乱する可能性はありません、
  • この場合、get追加のセマンティクスは伝達されず、
  • 私はこのget少ない命名スキーマをライブラリ全体で非常に一貫して使用しています。

CollectionJavaBeanの規則に違反するJavaクラス(およびJavaプラットフォームライブラリの他のクラス)からある程度の安心感を得ています(たとえば、size代わりに使用するgetSizeなど)。

この懸念を回避するには、コンポーネントをJavaBeanとして使用することはできません。これは、そのように意味のある方法で使用できないためです。

一方、私は経験豊富なJavaユーザーではなく、他のJava開発者がライブラリに何を期待しているのかわかりません。この中のJavaプラットフォームクラスの例に従うことはできますか、それとも悪いスタイルと見なされますか?getJavaライブラリクラスの/規則への違反は、set振り返ってみると間違いと見なされますか?または、該当しない場合にJavaBeanの規則を無視するのは完全に正常ですか?

JavaのSunコード規約では、これについてはまったく言及されていません。)

4

6 に答える 6

11

適切な命名規則に従えば、サードパーティのツールをライブラリと簡単に統合して使用できます。getX()彼らは、などを期待し、isX()反省を通してこれらを見つけようとします。

これらは現在JavaBeansとして公開されないとおっしゃっていますが、私は引き続き規則に従います。あなたが今後何をしたいかを誰が知っていますか?または、後の段階で、このオブジェクトへのインターフェイスを抽出し、他のツールを介してアクセスできるプロキシを作成する必要がありますか?

于 2009-09-07T12:46:37.943 に答える
6

私は実際にこの慣習が嫌いです。アクセサー/修飾子メソッドを提供する実際のJavaツールに置き換えられた場合、私は非常に起こります.

しかし、私はすべてのコードでこの規則に従います。私たちは単独でプログラムを作成しているわけではありません。チーム全体が今すぐ特別な規約に同意したとしても、将来の新規参入者やプロジェクトを維持する将来のチームは、最初は苦労することになるでしょう... get/set の不都合は、非標準であることによる不都合ほど大きくないと思います。


別の懸念を提起したいと思います。多くの場合、Java ソフトウェアはあまりにも多くのアクセサーと修飾子 (get/set) を使用します。「聞かずに教えて」というアドバイスをもっと適用する必要があります。たとえば、B のゲッターを「実際の」メソッドに置き換えます。

    class A {
      B b;
      String c;
      void a() {
        String c = b.getC();
        String d = b.getD();
        // algorithm with b, c, d
      }
    }

    class A {
      B b;
      String c;
      void a() {
        b.a(c); // Class B has the algorithm.
      }
    }

このリファクタリングにより、多くの優れたプロパティが得られます。

  • B は不変にすることができます (スレッドセーフに優れています)
  • B のサブクラスは計算を変更できるため、B はその目的のために別のプロパティを必要としない場合があります。
  • ゲッターやデータへの外部アクセスを使用する必要がなく、B 内にいて、実装の詳細を利用できるため (エラー、特殊なケースのチェック、キャッシュされた値...)。
  • より多くの結合がある B に配置されているため (A の 1 つではなく 2 つのプロパティ)、A のリファクタリングがアルゴリズムに影響を与えない可能性があります。B リファクタリングの場合、アルゴリズムを改善する機会になるかもしれません。そのため、メンテナンスは少なくなります。
于 2009-09-07T13:14:58.297 に答える
5

Javaライブラリクラスでのget/set規則の違反は、間違いなく間違いです。規則に従わない理由/時期を知ることの複雑さを避けるために、実際には規則に従うことをお勧めします。

于 2009-09-07T12:48:06.177 に答える
4

Josh Bloch は、 Effective Javaでこの問題について実際にあなたの側にいます。そこで彼はget、読みやすさのために、Bean として使用することを意図していないものに対して -less バリアントを提唱しています。もちろん、誰もが Bloch に同意するわけではありませんが、get. (その方が読みやすいと思うので、YAGNI の場合は. を捨ててgetください。)

size()コレクションフレームワークからのメソッドに関して; と を持つ最近のEnumクラスを見るname()と 、それが単に「悪い」レガシー名である可能性は低いようordinal()です。(これはおそらく Bloch がEnumの 2 人の著者のうちの 1 人であるということで説明できます。☺)

于 2009-09-07T13:51:43.490 に答える
2

get-less スキーマは、Scala (およびその他の言語) のような言語で、Uniform Access Principleとともに使用されます。

Scala はフィールド名とメソッド名を同じ名前空間に保持します。つまり、メソッドが count という名前の場合、フィールド count に名前を付けることはできません。Java などの多くの言語には、フィールド名とメソッド名を別々の名前空間に保持するため、この制限はありません。

Java は「プロパティ」に対して UAP を提供することを意図していないため、get/set 規則を使用してこれらのプロパティを参照することをお勧めします。

UAP とは:

  • Foo.barFoo.bar()は同じであり、読み取りプロパティ、またはプロパティの読み取りメソッドを参照します。
  • Foo.bar = 5Foo.bar(5)は同じであり、プロパティの設定またはプロパティの書き込みメソッドを参照してください。

Foo.barJava では、とFoo.bar()が 2 つの異なる名前空間にあるため、UAP を実現できません。
つまり、 read メソッドにアクセスするには、 を呼び出す必要がありますFoo.bar()。これは、他のメソッドを呼び出すのと同じです。
したがって、この get-set 規則は、その呼び出しを他のもの (プロパティに関連しない) と区別するのに役立ちます。これは、「モジュールによって提供されるすべてのサービス (ここでは、値の読み取り/設定、または計算のみ) は、統一表記」。
これは必須ではありませんが、プロパティ値の取得/設定または計算に関連するサービスを他のサービスから認識する方法です。
UAP が Java で使用できる場合、その規則はまったく必要ありません。

注: のsize()代わりにgetSize()、Java のマントラである「後方互換性: 常に」のために保存されている、おそらく従来の不適切な命名です。

于 2009-09-07T13:14:20.930 に答える
0

これを考慮してください:多くのフレームワークは、「名前」などのオブジェクトのフィールドのプロパティを参照するように指示できます。内部では、フレームワークは最初に「name」を「setName」に変換し、その特異なパラメーターから戻り値の型を特定し、「getName」または「isName」のいずれかを形成することを理解しています。

そのような十分に文書化された賢明なアクセサー/ミューテーターメカニズムを提供しない場合、フレームワーク/ライブラリは、他のライブラリ/フレームワークの大部分では機能しません。

于 2009-09-07T18:31:18.137 に答える