パッケージ名は単数か複数か? 読んだ後、私は自分の不快な点の1つをカバーする適切な議論、つまりインターフェイスの実装の名前付けを見たことがないことに気付きました。
さまざまな方法で実装することを目的としたインターフェースOrder
があると仮定しましょう。ただし、プロジェクトが最初に作成されたときの初期実装しかありません。誤った二分法を回避するために、DefaultOrder
やOrderImpl
などのバリアントを使用しますか?そして、より多くの実装がやってきたとき、あなたは何をしますか?
そして最も重要なのはなぜですか?
名前には意味を伝える機会があります。 Implでその機会を捨てるのはなぜですか?
まず第一に、実装が1つしかない場合は、インターフェースを廃止します。これにより、この命名の問題が発生し、何も追加されません。さらに悪いことに、あなたと他のすべての開発者が常にインターフェイスのみを使用するように注意していない場合、APIの一貫性のないメソッドシグネチャで問題が発生する可能性があります。
それを考えると、すべてのインターフェースがhasまたはを持っている可能性があると想定できます2つ以上の実装。
現在1つしかなく、もう1つがどのように違うのかわからない場合は、デフォルトから始めるのがよいでしょう。
現在2つある場合は、目的ごとにそれぞれに名前を付けます。
例:最近、具象クラスContext(データベースに関して)がありました。オフラインのコンテキストを表現できるようにする必要があることがわかったため、(古いAPIとの互換性を維持するために)Contextという名前が新しいインターフェースに使用され、新しい実装が作成されましたOfflineContext =。しかし、元の名前が何に変更されたと思いますか?そうです、ContextImpl(そうです)。
この場合、DefaultContextはおそらく大丈夫であり、人々はそれを理解するでしょうが、それは可能な限り説明的ではありません。結局のところ、オフラインではない場合、それは何ですか?それで、私たちはOnlineContextを使いました。
特殊なケース:インターフェースで「I」接頭辞を使用する
その他の回答 の1つは、インターフェースでIプレフィックスを使用することを提案しました。できれば、これを行う必要はありません。
ただし、カスタム実装のために両方のインターフェースが必要であるが、頻繁に使用されるprimary具象実装もある場合、その基本的な名前はインターフェースをあきらめるには単純すぎる単独の場合は、インターフェイスに「I」を追加することを検討できます(ただし、それでもまだ自分やチームに適切に配置されていなくても問題ありません)。
例:多くのオブジェクトは「EventDispatcher」になることができます。 APIのために、これはインターフェースに準拠する必要があります。ただし、委任用にbasicイベントディスパッチャも提供する必要があります。 DefaultEventDispatcherで構いませんが、少し長いので、その名前が頻繁に表示される場合は、を使用する可能性がありますベース名EventDispatcher具象クラスの場合、実装IEventDispatcherカスタム実装の場合:
/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
/* default event dispatcher */
}
/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
/* default event dispatcher. */
}
ネーミングはインターフェースのユースケースで決めています。
インターフェイスがdecouplingに使用されている場合、実装にはImpl
を選択します。
インターフェースの目的が振る舞いの抽象化の場合、実装は具体的に何をしているかに従って名前が付けられます。私はしばしばそれにインターフェース名を追加します。したがって、インターフェイスがValidator
と呼ばれる場合、FooValidator
を使用します。
Default
は非常に悪い選択です。名前は常にそれで始まるため、最初にコード補完機能を汚染します。もう1つは、デフォルトは時間の経過とともに変更される可能性があることです。したがって、最初にデフォルトになる可能性のある機能は、非推奨の機能になる可能性があります。したがって、デフォルトが変更されるとすぐにクラスの名前を変更し始めるか、誤解を招く名前を付けて住んでいます。
私はニコールの回答に同意します(特に、ほとんどの場合、インターフェイスはおそらく必要ないでしょう)が、議論のために、OrderImpl
およびDefaultOrder
以外の追加の代替案を捨てます。 Orders.create()
のような静的ファクトリメソッドの背後に実装を隠す。例えば:
public final class Orders {
public static Order create() {
return new Order() {
// Implementation goes here.
};
}
}
このアプローチでは、実装は匿名の内部クラスであるか、名前にDefault
またはImpl
が含まれるプライベートクラスであるか、完全に別の名前が付けられている可能性があります。どちらを選択しても、呼び出し元は気にする必要がないので、後で変更することを決定した場合に、柔軟性が高まります。
実際のこのパターンのいくつかの優れた例は、Java.util.Collections
およびJava.util.concurrent.Executors
ユーティリティクラスで、これらのメソッドは非表示の実装を返します。効果的なJavaの言及(アイテム1))のように、このパターンはAPIの「概念上の重み」を小さく保つのに役立ちます。
OrderImpl
インターフェイスの直後にアルファベット順に表示されるため、私は常にOrder
を使用します。
デフォルトはいくつかのケースで意味をなすことができますが、実装を説明する方が役立つと思います。したがって、インターフェースがUserProfileDAO
の場合、実装はUserProfileSQLDAO
またはUserProfileLDAPDAO
またはそのようなものにすることができます。
可能であれば、何をどのように実行するかから名前を付けます。
通常、最悪のアプローチは、使用方法に基づいて名前を付けることです。
実装の基本クラスとして使用することになっている場合は、BaseXまたはAbstractXを使用できます(それが抽象の場合(ただし、それを何もしないようにしてください)。インターフェース)。これが可能な限り単純な機能を提供し、そのような機能が十分であるときに直接(拡張ではなく)使用されることが予想される場合は、SimpleXまたはBasicXと呼ぶことができます。
他の実装が提供されていない場合に使用する場合は、DefaultXという名前を付けます。
インターフェースよりもクラスについて具体的または具体的なものを理解し、それを名前に組み込んでみてください。
データを永続化するためのインターフェースがあるとしましょう、FooDao。永続化は、フラットファイル、XMLドキュメント、スプレッドシート、リレーショナルデータベース、非リレーショナルデータベースなどに対して行うことができます。クラスがデータをSQLデータベースに永続化している場合は、FooSqlがFooDaoを実装してみてください。
リレーショナルデータベースベンダーに固有のコードがある場合は、FooMssql、FooOracle、またはFooDb2を試してください。または、FooDaoMssqlまたはFooDaoPostgreの方が目的に適しています。
重要なのは、一意の識別子を作成する目的のみを果たす文字を追加するのではなく、より意味のある名前を付けてください。これには2つの効果があります。実装クラスが1つしかない場合でも、次の開発者に多くの意味を伝えます。実装クラスが1つだけの場合でも、別の実装が必要になったとしても、.. Implと..Impl2、または..Implと..Mongoのような名前は見つかりません。
プレフィックスI(IWhatever)を使用してインターフェイスに名前を付け、実装をWhateverにすることができます。
公式Javaコード規約では、インターフェイスのこの種の命名については触れていませんが、この種の命名は認識とナビゲーションに役立ちます。