web-dev-qa-db-ja.com

Javaインタフェース/実装命名規則

自分が作成したさまざまなクラス/インターフェースにどのように名前を付けますか?実装名に追加するための実装情報がない場合があります。インタフェースFileHandlerやクラスSqlFileHandlerなどです。

これが起こるとき、私は通常Truckのように "通常の"名前でインターフェースを命名し、実際のクラスをTruckClassと命名します。

この点で、インターフェイスとクラスにどのような名前を付けますか。

298
Amir Rachum

Interfaceという名前を付けます。 TruckITruckではないので、ITruckではありません。Truckです。

JavaのInterfaceは、 Type です。それから、DumpTruckTransferTruckWreckerTruckCementTruckなどのimplement Truckがあります。

サブクラスの代わりにInterfaceを使用している場合は、それをTruckにキャストするだけです。 List<Truck>と同じです。 Iを前に置くことは、単に ハンガリースタイル の表記 のトートロジー です。

最近のすべてのJava IDEのマークは、インターフェースと実装であり、このばかげた表記がないのはそのためです。 TruckClass、つまり tautologyIInterface tautologyと同じくらい悪いとは言わないでください。

実装であればクラスです。この規則に対する唯一の本当の例外は、そしていつも例外がある、AbstractTruckのようなものかもしれません。サブクラスだけがこれを見て、Abstractクラスに決してキャストしてはいけないので、それはそのクラスが抽象的であるといういくらかの情報とそれがどのように使われるべきかに追加します。 AbstractTruckが定義に含まれているので、BaseTruckよりも良い名前を思いついて代わりにDefaultTruckまたはabstractを使用することもできます。しかし、Abstractクラスは、一般向けのインターフェイスの一部にしないでください。これは、この規則の受け入れ可能な例外です。コンストラクタをprotectedにすると、この格差を超えることができます。

そしてImpl接尾辞は、単なるノイズです。より多くのトートロジーインタフェースではないものはすべて実装です。部分的な実装である抽象クラスでさえもです。すべての クラス のすべての名前に、その馬鹿げたImplという接尾辞を付けますか。

Interfaceは、パブリックメソッドとプロパティがサポートする必要があるものに関する規約です。また、 Type 情報でもあります。 Truckを実装するものはすべてTruckType です。

Java標準ライブラリ自体を見てください。 IListArrayListImplLinkedListImplが表示されていますか。いいえ、ListArrayList、およびLinkedListが表示されます。これは、この正確な質問に関するNice の記事 です。これらの愚かな接頭辞/接尾辞の命名規則はすべて DRY の原則にも違反しています。

また、オブジェクトにDTOJDOBEAN、またはその他の愚かな繰り返しのサフィックスを追加した場合、それらは パッケージに属していることになります これらの接尾辞すべての代わりに。適切にパッケージ化された名前空間は自己文書化され、ほとんどの場所でさえ一貫して内部的に固執していない、これらの本当によく考えられていない独自の命名体系におけるすべての無用な冗長情報を減らします。

Classを一意にするために思いついたことがすべてImplの接尾辞に付いている場合は、Interfaceを持つことを再考する必要があります。 したがって、InterfaceImplementationから一意的に特殊化されていないInterfaceが1つだけある状況では、おそらく必要ないでしょう。 Interface

823
user177800

ここで答えを見たことがあるのですが、実装が1つしかなければインターフェースは必要ないということです。これはDepencency Injection/Inversion of Controlの原則に反して飛んできます(電話しないでください、電話します)。

そのため、コードを単純化し、注入されたインタフェースの実装に依存することで簡単にテストできるようにしたい場合があります(これはプロキシになることもあります - あなたのコードにはわかりません)。 2つの実装しかない場合でも、1つはテスト用のMock、もう1つは実際の本番コードに挿入されます。これは、インタフェースを持つことを不必要にすることにはなりません。よく文書化されたインターフェースは、テストのための厳密なモック実装によっても維持されることができる契約を確立します。

実際、モックに最も厳格なインタフェース規約を実装するテスト(nullであってはならない引数の例外をスローするなど)を確立し、プロダクションコードでより効率的な実装を使用してテストエラーをキャッチすることができます。あなたのテストではモックが例外を投げたのでnullであってはいけません。例えば、これらのテストの後にコードを修正したために引数がnullではないことがわかります。

Dependency Injection/IOCは新参者を掴むのが難しいかもしれませんが、その可能性を理解したらそれをいたるところで使いたくなるでしょう。実生産)の実装。

この1つの実装(テスト用のモックはMock(InterfaceName)と呼ぶべきだと私は信じています)、私はDefault(InterfaceName)という名前を好みます。より具体的な実装が登場した場合は、適切な名前を付けることができます。これはまた私が特に嫌いなImpl接尾辞を避けます(もしそれが抽象クラスでなければ、OF COURSEそれは「暗黙の」です!)。

"Abstract(InterfaceName)"よりも "Base(InterfaceName)"を好むのですが、後で基底クラスをインスタンス化できるようにしたい場合があるので、ここでは "Abstract(InterfaceName)"という名前で行き詰まっています。これは、クラス名を変更することを余儀なくし、多少の混乱を招く可能性があります。ただし、Base(InterfaceName)が常にBaseである場合は、抽象修飾子を削除してもクラスの内容は変わりません。

95
MetroidFan2002

インタフェースの名前は、そのインタフェースが表す抽象概念を記述しなければなりません。どの実装クラスにも、より具体的な名前を付けるために使用できるある種の固有の特性があるはずです。

実装クラスが1つしかなく、それを特定のものにすることができない(-Implという名前を付けたいという意味で)ことができない場合、インタフェースを持つことの正当性がまったくないように見えます。

60

私はJava Core/Sunによって確立された擬似規約に従う傾向があります。 Collectionsクラスで:

  • List - 「概念的」なオブジェクトのインタフェース
  • ArrayList - インターフェースの具体的な実装
  • LinkedList - インターフェースの具体的な実装
  • AbstractList - カスタム実装を支援する抽象 "部分的"実装

AWTのEvent/Listener/Adapterパラダイムの後に、私は自分のイベントクラスをモデル化するのと同じことをしていました。

31
Bert F

Javaでも十分に機能する標準のC#規則では、すべてのインターフェイスの前にIを付けることです。したがって、ファイルハンドラインターフェイスはIFileHandlerになり、トラックインターフェイスはITruckになります。それは一貫性があり、クラスからインターフェースを見分けるのを簡単にします。

28
tzaman

私は、 "Comparable"や "Serializable"のように、インターフェースがどのような規約を表すのかを示すインターフェース名が好きです。 「トラック」のような名詞は実際にトラックのネスを説明していません - トラックの能力は何ですか?

規約について:私はすべてのインターフェースが "I"で始まるプロジェクトに取り組んできました。これはJavaの規約とは多少異質ですが、インタフェースを見つけるのはとても簡単です。それとは別に、 "Impl"接尾辞は妥当なデフォルト名です。

21
mfx

これを好まない人もいますし、それはJavaよりも.NETの慣習ですが、あなたはあなたのインターフェースに大文字のI接頭辞をつけることができます、例えば:

IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations

この命名規則に反対する人々は、あなたがコードの中でインターフェースとオブジェクトのどちらを使って作業しているのかを気にするべきではないと主張するかもしれません。

実装クラスに "Class"サフィックスを付けないでください。コード内では実際には「クラス」(つまりType)オブジェクトを扱うことができるので、混乱を招く可能性がありますが、この場合は、クラスオブジェクトを扱うのではなく、単に古いオブジェクトを扱うだけです。 。

9
Andy White

TruckClassname__はTruckname__のクラスのように思えますが、推奨される解決策はImplname__という接尾辞を追加することです。私の意見では、最善の解決策はインプリメンテーション名の中にその特定のインプリメンテーションで起こっていること(Listname__インターフェースやインプリメンテーション:ArrayListname__やLinkedListname__のように) (たとえば)リモートでの使用には、(最初​​に述べたように)Implname__が解決策です。

1
Mirek Pluta

私は両方の規約を使います。

インターフェースが既知のパターンの特定のインスタンス(Service、DAOなど)の場合は、 "I"(UserService、AuditService、UserDaoなど)のすべてが正常に動作する必要はない場合があります。メタパターンを決定します。

しかし、(通常コールバックパターンのために)1回限りまたは2回限りのものがある場合は、それをクラスと区別するのに役立ちます(例:IAsynchCallbackHandler、IUpdateListener、IComputeDrone)。これらは内部使用のために設計された特別な目的のインターフェースです、時にはIInterfaceはオペランドが実際にはインターフェースであるという事実に注意を喚起するので、一見するとすぐに明らかです。

それ以外の場合には、Iを使用して、一般的に知られている他の具象クラス(ISubject、IPrincipal vs Subject、またはPrincipal)と衝突しないようにすることができます。

1
Justin