Javaでのインターフェースの命名[終了]


324

ほとんどのOO言語は、インターフェース名の前に大文字のIを付けています。なぜJavaはこれを行わないのですか?この規則に従わない理由は何でしたか?

つまり、ユーザーインターフェイスとユーザー実装が必要な場合は、Javaで2つの選択肢があります。

  1. クラス=ユーザー、インターフェース=ユーザーインターフェース
  2. クラス= UserImpl、インターフェース= User

ほとんどの言語で:

クラス=ユーザー、インターフェース= IUser

今、あなたは常にユーザー実装に最も説明的な名前を選ぶことができ、問題はなくなると主張するかもしれませんが、Javaは物事へのPOJOアプローチを推進しており、ほとんどのIOCコンテナーはDynamicProxiesを広範囲に使用しています。これら2つのことを合わせると、1つのPOJO実装で多くのインターフェースができることになります。

つまり、私の質問は次のように要約されていると思います。「特に、Javaフレームワークが向かっているように見える場所を考慮して、より広いインターフェース命名規則に従う価値はありますか?」


61
「どこの言語で」?.NET以外の言語は何ですか?
wds

2
言語コミュニティが異なれば命名規則も異なります。これは長い間当てはまっていました。命名規則がどのように始まったかを知ることは、時には本質的に民間伝承の研究です。
David Thornley、

4
Eclipseは、IFooスタイルの命名でJavaを使用する重要な外れ値です。 wiki.eclipse.org/Naming_Conventions
デビッドレナード

2
あなたは(Javaなども)のAndroid SDKのインターフェイスの名前を見てみる場合は、次のような、彼らはインタフェース名の末尾に単語のインターフェイスを持つの規則を使用していることがわかりますNetworkInterfaceDialogInterfaceなど、
sandalone

21
この質問が非常に人気があり、非常に多くの人々に関心がある場合、この質問を「建設的ではないように閉じる」ことができるでしょうか。
2014

回答:


329

私はインターフェースでプレフィックスを使用したくない:

  • 接頭辞は読みやすさを損ないます。

  • クライアントでインターフェイスを使用することは、プログラミングの標準的な最良の方法です。そのため、インターフェイス名はできるだけ短く、わかりやすいものにする必要があります。クラスの実装は、使用を阻止するために醜くする必要があります。

  • 抽象クラスからインターフェースに変更するとき、接頭辞付きのコーディング規約は、クラスのすべてのオカレンスの名前を変更することを意味します---良くありません!


12
完全に同意する。オートコンプリートを使用する場合に入力するもう1つのキー。Iで始まる多数のファイル
Kalecser

85
まともなIDEなら、記述している方法でコードを簡単に変更できます。また、抽象クラスからインターフェイスに変更する場合、クライアントはとにかく再コンパイルする必要があると確信しています。
Allain Lalonde、

63
ここで非常に遅いですが、IDEが何かの名前を簡単に変更できるかどうかはまったく問題はありません。あるタイプのインスタンスを使用するコードは、そのタイプがインターフェースかクラスか、または何であるかを気にすることはありません。そのため、そのような詳細を型の名前で公開することは無意味であり、理解に有害です。タイプとそれが公開するコントラクトが重要です!
ColinD 2011年

11
その上、もしあなたがIFooのルートを進んでいるなら、それは実装のためのCFooであるべきではなく、もちろん失敗した場合、メソッドはEFooをスローします。
Robin

57
「プレフィックスは読みやすさを損なう」は純粋に主観的なものです。ほとんどの命名規則と同様に。コードベースの一貫性を保つために、チームが何をすべきかについての合意を決めることがより重要です。
dreadwail

121

本当に違いはありますか:

class User implements IUser

そして

class UserImpl implements User

私たちが話しているすべてが命名規則であるなら?

個人的には、インターフェースのIコーディングをしたいので、インターフェースの前に置かない方が好きで、命名規則の観点からは、それがより重要であると考えいます。インターフェースを呼び出す場合IUser、そのクラスのすべてのコンシューマーはそのを知る必要がありIUserます。クラスを呼び出すと、クラスUserImplとDIコンテナーImplだけがパーツを認識し、コンシューマーはで作業していることだけを認識しますUser

繰り返しになりますImplが、適切な名前が表示されないために使用を余儀なくされた回数は、実装に応じて名前が付けられるため、ほとんどありません。

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

DAOはクラスを開かなくても一般的な機能を説明できるので、DAOについて知りたいと思います。プロジェクトのクラスファイルを見る場合、* DAOを検索することですべてのDAOを簡単に確認できます
Patrick

6
DAOはデータベースアクセスのよく知られたパターンであるため、名前にパターンを含めると、名前を見ただけでクラスの機能を簡単に知ることができます。PS mina.apache.org/changes-between-2x-and-1x.html
Esko Luontola

4
@marker、それはインターフェースを示すためにIを持っているようなものではありません。DAOは、クラスまたはインターフェイスがアカウントデータにアクセスするためのオブジェクトであることを通知します。これは、オブジェクトが行うことです。Iがあると、そのインターフェースはオブジェクト自体とは関係ありませんが、言語のセマンティクスです
tddmonkey '13

あなたがそれを提示するとき、そのプレフィックス対サフィックス。
AndreiRînea2010年

3
@Andrei:いいえ、それはセマンティクス( "DAO")と言語アーティファクトの不必要な装飾(インターフェイスの "I"です。事実、とにかくコードで言及されている "インターフェイスIFoo ...")
Dirk

75

Javaが一般にIUser規則を使用しない理由はいくつかあります。

  1. オブジェクト指向アプローチの一部は、クライアントがインターフェースを使用しているか、実装クラスを使用しているかを知る必要がないことです。そのため、ListがインターフェースでStringが実際のクラスである場合でも、メソッドは両方に渡される可能性があります。インターフェースを視覚的に区別しても意味がありません。

  2. 一般的に、実際にはクライアントコードでのインターフェイスの使用を優先します(たとえば、ArrayListよりもListを優先します)。したがって、インターフェイスを例外として目立たせることは意味がありません。

  3. Javaの命名規則では、ハンガリー語スタイルの接頭辞よりも実際の意味を持つ長い名前を優先しています。そのコードは可能な限り読みやすくなります。リストはリストを表し、ユーザーはIUserではなくユーザーを表します。


72

Springを含む多くのオープンソースプロジェクトで使用されている別の規約もあります。

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

私は個人的に、「I」接頭辞がオプションの規則であるという単純な理由で、好きではありません。これを採用すると、IIOPConnectionはIOPConnectionのインターフェースを意味するのでしょうか?クラスに「I」プレフィックスがない場合はどうなりますか?それから、インターフェースではないことを知っていますか?ここでは答えはノーです。これは、規則が常に守られているわけではないためです。


これは、クラスを結合するのではなく、外部依存関係のインターフェースを使用するモードにもなります。
Matt Briggs、

47

別のポスターが言ったように、タイプではなく機能を定義するインターフェースを持つことが一般的に望ましいです。私は「ユーザー」のようなものを「実装」する傾向はありません。そのため、ここで説明する方法では「IUser」は必ずしも必要ではないことがよくあります。私はしばしばクラスを名詞と見なし、インターフェースを形容詞と見なしています。

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

時々形容詞は意味をなさないかもしれませんが、私はまだ一般的に振る舞い、アクション、機能、プロパティなどをモデル化するためにインターフェースを使用しています...型ではありません。

また、本当に1人のユーザーを作成し、それをユーザーと呼ぶつもりなら、IUserインターフェイスも持つ意味は何ですか?また、共通のインターフェースを実装する必要があるいくつかのタイプのユーザーがいる場合、インターフェースに「I」を追加すると、実装の名前を選択するときに何が節約できますか?

より現実的な例としては、特定のAPIにログインできるようにする必要があるタイプのユーザーがいるでしょう。Loginインターフェースを定義し、SuperUser、DefaultUser、AdminUser、AdministrativeContactなどのサブクラスを持つ「User」親クラスを作成できます。これらの一部は、必要に応じてLogin(Loginable?)インターフェースを実装するか、実装しません。


あなたが「形容詞としてのインターフェース」をサポートするために提供する例は歪んでいると思います。これらのインターフェースはミックスイン(またはトレイト)のように意図されているからです。したがって、インターフェースは形容詞と名詞の両方に適していますが、おそらくindefinite transitive verbs 8 ^ Pには適していません
Stevel

これはここ数年で変更される可能性があります。神託文書。タイプとしてインターフェイスを許可:[リンク] docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
karlihnos

38

ボブ・リーはプレゼンテーションで一度言った:

実装が1つしかない場合のインターフェースの要点。

したがって、1つの実装、つまりインターフェースなしで開始します。後で決めるのは、まあ、ここにインターフェイスが必要なので、クラスをインターフェイスに変換することです。

その後、それが明らかになります。元のクラスはUserと呼ばれていました。あなたのインターフェースは現在Userと呼ばれています。多分あなたはUserProdImplとUserTestImplを持っています。アプリケーションを適切に設計した場合、すべてのクラス(Userをインスタンス化するクラスを除く)は変更されず、突然インターフェイスに渡されることに気付かないでしょう。

そのため、明らかになります->インターフェイスユーザー実装UserImpl。


18
インターフェイスの使用は、テスト駆動開発を支援します。インターフェースを使用しないことにしたため、ドメインモデルとテストで多くの問題に遭遇しました。私の友人はかつて引用した:「すべてがインターフェースであり、それは長い目で見ればあなたを救うでしょう。」
hooknc 2009

4
モッキングと簡単なプロキシのサポート。インターフェイスを提供する理由は他にもあると思います。
MetroidFan2002

3
最近同僚に言ったように、インターフェースを導入するのに費用はかかりませんが、後でかなりの時間を節約できます。
tddmonkey 2009

2
中程度の将来に他の実装がある可能性がある場合、インターフェイスはプラスになります。
Stef、2009

3
「将来は別の実装が必要になるかもしれない」という議論は好きではありません。私はYAGNIアプローチを好みます。まだ起こっていないことを計画しないでください。
David Lavender

24

C#では

public class AdminForumUser : UserBase, IUser

Javaは言うだろう

public class AdminForumUser extends User implements ForumUserInterface

そのため、継承とインターフェイスの実装には明確な違いがあるため、インターフェイスのJavaでは規約はそれほど重要ではないと思います。一貫性があり、インターフェースであることを人々に示すために何かを使用している限り、好きな命名規則を選択するだけです。数年でJavaを実行していませんが、すべてのインターフェイスは独自のディレクトリにあり、それが慣例でした。実際には問題はありませんでした。


22
多分私は悪いJavaコーダーですが、私はC#スタイルを好みます、それはすべてのインターフェースが「I」プレフィックスで始まることを意味します:)
davs

7
あなたや他の人がこの想定された慣習をどこから得ているのかわかりません。Javaライブラリでは明らかではありません...
ChiefTwoPencils 2015

6

私の経験では、「I」の規則は、特にインターフェース自体がクラスの抽象的な概念ではない場合に、クラスへのコントラクトを提供することを目的としたインターフェースに適用されます。

たとえば、あなたのケースでは、あなたIUserが持っているつもりの唯一のユーザーがであるかどうかを確認することだけを期待していますUser。-あなたは、ユーザーのさまざまな種類持つように計画している場合NoviceUserExpertUserなどを、 -私が見ることを期待するUserインターフェース(と、おそらく、AbstractUserクラス実装はいくつかの共通の機能、のようなことをget/setName())。

また、機能を定義するインターフェース-、、- などComparableIterable、そのように名前が付けられており、IComparableまたはのような名前ではないことを期待しますIIterable


持っているつもりのユーザーがユーザーのみの場合は、インターフェースの代わりにユーザーを使用してみませんか?
カリガン2017年

3
一部のクライアント/サーバーアーキテクチャでは、クライアント側は、重いサーバーの実装を必要とせずにインターフェースを知る必要があります。
David Koelle

5

適切なOO原則に従って、コードは(実用的/可能な限り)具体的なクラスではなく抽象化に依存する必要があります。たとえば、一般的には次のようなメソッドを記述する方が適切です。

public void doSomething(Collection someStuff) {
    ...
}

これより:

public void doSomething(Vector someStuff) {
    ...
}

このアイデアに従えば、 "IUser"や "UserInterface"などのバリエーションではなく、 "User"や "BankAccount"などのインターフェイス名を指定すると、コードが読みやすくなると思います。

実際の具象クラスに注意する必要があるコードは、具象クラスが構築される場所だけです。その他はすべて、インターフェースを使用して作成する必要があります。

これを行う場合、「UserImpl」などの「醜い」具象クラス名は、コードの残りの部分から安全に非表示にする必要があります。これにより、「素敵な」インターフェース名を使用できます。


しかし、1つまたは2つのもののインターフェースだけが必要なときに、プログラムのすべてのクラスに一致するインターフェースを作成する必要があるのはなぜですか。
LegendLength 2016年

3

= v =「I」接頭辞はWicketフレームワークでも使用されており、すぐに慣れました。一般に、面倒なJavaクラス名を短くするあらゆる規約を歓迎します。ただし、ディレクトリとJavadocの「I」の下にすべてアルファベット順になっているのは面倒です。

Wicketのコーディング方法はSwingに似ていますが、多くのコントロール/ウィジェットインスタンスは、インラインメソッド宣言を持つ匿名の内部クラスとして構築されます。厄介なことに、Swingは実装クラスに接頭辞( "J")を使用するという点でSwingと180°異なります。

「Impl」サフィックスは、非常に複雑な略語であり、国際化がうまくいっていません。少なくとも "Imp"を使用していれば、それはよりかわいい(そしてより短い)でしょう。"Impl"はIOC、特にSpringに使用されているので、今のところはそれにこだわっています。ただし、1つのコードベースの3つの異なる部分にある3つの異なる規則に従って、少し簡単になります。


0

これは、本当の意味でのより広い命名規則ですか?私はC ++のほうが好きで、Javaやその子孫についてはあまり気にしていません。I規約を使用する言語コミュニティはいくつありますか?

ここに言語に依存しないショップ標準の命名規則がある場合は、それを使用してください。そうでない場合は、言語の命名規則に従ってください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.