自分が作成したさまざまなクラス/インターフェースにどのように名前を付けますか?実装名に追加するための実装情報がない場合があります。インタフェースFileHandler
やクラスSqlFileHandler
などです。
これが起こるとき、私は通常Truck
のように "通常の"名前でインターフェースを命名し、実際のクラスをTruckClass
と命名します。
この点で、インターフェイスとクラスにどのような名前を付けますか。
Interface
という名前を付けます。 Truck
。 ITruck
ではないので、ITruck
ではありません。Truck
です。
JavaのInterface
は、 Type です。それから、DumpTruck
、TransferTruck
、WreckerTruck
、CementTruck
などのimplement Truck
があります。
サブクラスの代わりにInterface
を使用している場合は、それをTruck
にキャストするだけです。 List<Truck>
と同じです。 I
を前に置くことは、単に ハンガリースタイル の表記 のトートロジー です。
最近のすべてのJava IDEのマークは、インターフェースと実装であり、このばかげた表記がないのはそのためです。 TruckClass
、つまり tautology をIInterface
tautologyと同じくらい悪いとは言わないでください。
実装であればクラスです。この規則に対する唯一の本当の例外は、そしていつも例外がある、AbstractTruck
のようなものかもしれません。サブクラスだけがこれを見て、Abstract
クラスに決してキャストしてはいけないので、それはそのクラスが抽象的であるといういくらかの情報とそれがどのように使われるべきかに追加します。 AbstractTruck
が定義に含まれているので、BaseTruck
よりも良い名前を思いついて代わりにDefaultTruck
またはabstract
を使用することもできます。しかし、Abstract
クラスは、一般向けのインターフェイスの一部にしないでください。これは、この規則の受け入れ可能な例外です。コンストラクタをprotected
にすると、この格差を超えることができます。
そしてImpl
接尾辞は、単なるノイズです。より多くのトートロジーインタフェースではないものはすべて実装です。部分的な実装である抽象クラスでさえもです。すべての クラス のすべての名前に、その馬鹿げたImpl
という接尾辞を付けますか。
Interface
は、パブリックメソッドとプロパティがサポートする必要があるものに関する規約です。また、 Type 情報でもあります。 Truck
を実装するものはすべてTruck
の Type です。
Java標準ライブラリ自体を見てください。 IList
、ArrayListImpl
、LinkedListImpl
が表示されていますか。いいえ、List
とArrayList
、およびLinkedList
が表示されます。これは、この正確な質問に関するNice の記事 です。これらの愚かな接頭辞/接尾辞の命名規則はすべて DRY の原則にも違反しています。
また、オブジェクトにDTO
、JDO
、BEAN
、またはその他の愚かな繰り返しのサフィックスを追加した場合、それらは パッケージに属していることになります これらの接尾辞すべての代わりに。適切にパッケージ化された名前空間は自己文書化され、ほとんどの場所でさえ一貫して内部的に固執していない、これらの本当によく考えられていない独自の命名体系におけるすべての無用な冗長情報を減らします。
Class
を一意にするために思いついたことがすべてImpl
の接尾辞に付いている場合は、Interface
を持つことを再考する必要があります。 したがって、Interface
とImplementation
から一意的に特殊化されていないInterface
が1つだけある状況では、おそらく必要ないでしょう。 Interface
ここで答えを見たことがあるのですが、実装が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である場合は、抽象修飾子を削除してもクラスの内容は変わりません。
インタフェースの名前は、そのインタフェースが表す抽象概念を記述しなければなりません。どの実装クラスにも、より具体的な名前を付けるために使用できるある種の固有の特性があるはずです。
実装クラスが1つしかなく、それを特定のものにすることができない(-Impl
という名前を付けたいという意味で)ことができない場合、インタフェースを持つことの正当性がまったくないように見えます。
私はJava Core/Sunによって確立された擬似規約に従う傾向があります。 Collectionsクラスで:
List
- 「概念的」なオブジェクトのインタフェースArrayList
- インターフェースの具体的な実装LinkedList
- インターフェースの具体的な実装AbstractList
- カスタム実装を支援する抽象 "部分的"実装AWTのEvent/Listener/Adapterパラダイムの後に、私は自分のイベントクラスをモデル化するのと同じことをしていました。
Javaでも十分に機能する標準のC#規則では、すべてのインターフェイスの前にI
を付けることです。したがって、ファイルハンドラインターフェイスはIFileHandler
になり、トラックインターフェイスはITruck
になります。それは一貫性があり、クラスからインターフェースを見分けるのを簡単にします。
私は、 "Comparable"や "Serializable"のように、インターフェースがどのような規約を表すのかを示すインターフェース名が好きです。 「トラック」のような名詞は実際にトラックのネスを説明していません - トラックの能力は何ですか?
規約について:私はすべてのインターフェースが "I"で始まるプロジェクトに取り組んできました。これはJavaの規約とは多少異質ですが、インタフェースを見つけるのはとても簡単です。それとは別に、 "Impl"接尾辞は妥当なデフォルト名です。
これを好まない人もいますし、それはJavaよりも.NETの慣習ですが、あなたはあなたのインターフェースに大文字のI接頭辞をつけることができます、例えば:
IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations
この命名規則に反対する人々は、あなたがコードの中でインターフェースとオブジェクトのどちらを使って作業しているのかを気にするべきではないと主張するかもしれません。
実装クラスに "Class"サフィックスを付けないでください。コード内では実際には「クラス」(つまりType)オブジェクトを扱うことができるので、混乱を招く可能性がありますが、この場合は、クラスオブジェクトを扱うのではなく、単に古いオブジェクトを扱うだけです。 。
TruckClass
name__はTruck
name__のクラスのように思えますが、推奨される解決策はImpl
name__という接尾辞を追加することです。私の意見では、最善の解決策はインプリメンテーション名の中にその特定のインプリメンテーションで起こっていること(List
name__インターフェースやインプリメンテーション:ArrayList
name__やLinkedList
name__のように) (たとえば)リモートでの使用には、(最初に述べたように)Impl
name__が解決策です。
私は両方の規約を使います。
インターフェースが既知のパターンの特定のインスタンス(Service、DAOなど)の場合は、 "I"(UserService、AuditService、UserDaoなど)のすべてが正常に動作する必要はない場合があります。メタパターンを決定します。
しかし、(通常コールバックパターンのために)1回限りまたは2回限りのものがある場合は、それをクラスと区別するのに役立ちます(例:IAsynchCallbackHandler、IUpdateListener、IComputeDrone)。これらは内部使用のために設計された特別な目的のインターフェースです、時にはIInterfaceはオペランドが実際にはインターフェースであるという事実に注意を喚起するので、一見するとすぐに明らかです。
それ以外の場合には、Iを使用して、一般的に知られている他の具象クラス(ISubject、IPrincipal vs Subject、またはPrincipal)と衝突しないようにすることができます。