web-dev-qa-db-ja.com

Javaでのインターフェースの命名

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

私が何を意味するのかを説明するために、ユーザーインターフェースとユーザー実装を使いたいのであれば、Javaには2つの選択肢があります。

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

ほとんどの言語のどこで:

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

さて、あなたはいつもユーザー実装のために最もわかりやすい名前を選ぶことができて問題がなくなると主張するかもしれません、しかし物事へのPOJOアプローチを押すJavaとほとんどのIOCコンテナはDynamicProxiesを広範囲に使います。これら2つのことをまとめると、単一のPOJO実装に対して多数のインタフェースがあることになります。

「特にJavaフレームワークが向かっているように見える点を考慮すると、より広いInterface命名規則に従う価値がありますか?」

304
Allain Lalonde

私はインターフェースにプレフィックスを使わない方がいいです

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

  • クライアントでインタフェースを使用するのがプログラムするための標準的な最善の方法であるので、インタフェース名はできるだけ短くて快適であるべきです。クラスを実装することは、それらの使用を妨げるためにはより賢明であるべきです。

  • 抽象クラスからインタフェースに変更するとき、接頭辞Iの付いたコーディング規約は、そのクラスのすべての出現箇所の名前を変更することを意味します。

308
starblue

本当に違いがありますか?

class User implements IUser

そして

class UserImpl implements User

私たちが話しているのが命名規則だけであるならば?

個人的には、私はインターフェースをコーディングしたいのでIをインターフェースの前に付けないことを好みます、そして that は命名規則の観点からもっと重要であると考えます。インターフェースIUserを呼び出す場合、そのクラスのすべてのコンシューマーはそのIUserを知っている必要があります。クラスUserImplを呼び出すと、クラスとDIコンテナだけがImpl部分を認識し、コンシューマはUserを処理していることを認識します。

それでもやはり、私はImplを使うことを強いられた時代は、それ自身が存在しないという理由で、実装が に従って のように命名されるので、ほんの少しの間だけでした。

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
106
tddmonkey

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

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

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

  3. Javaの命名規則では、ハンガリー語の接頭辞に対して実際の意味を持つ長い名前が優先されます。そのため、そのコードはできるだけ読みやすくなります。Listはリストを表し、Userはユーザーを表します。IUserではなくです。

74
Avi

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

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

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

70
ng.

別の投稿者が言ったように、通常はインターフェースに型ではなく機能を定義させるのが好ましいです。私は「ユーザー」のようなものを「実装」しない傾向があります、そしてこれが「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?)インタフェースを実装するかどうかを決定します。

44
nairbv

Bob Leeはプレゼンテーションで一度も述べています。

実装が1つしかない場合は、インターフェイスのポイントは何ですか。

それで、あなたは1つの実装、すなわちインタフェースなしで始めます。後であなたが決めるのは、まあ、ここではインターフェースが必要だと思うので、あなたは自分のクラスをインターフェースに変換します。

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

だからそれは明確になる - >インターフェイスユーザー実装UserImpl。

36

C#では

public class AdminForumUser : UserBase, IUser

Javaは言うだろう

public class AdminForumUser extends User implements ForumUserInterface

そのため、継承とインタフェースの実装には明確な違いがあるので、規約はJavaにとってインタフェースにとってそれほど重要ではないと思います。私は、あなたが一貫していて、これらがインターフェースであることを人々に示すために何かを使う限り、あなたが望むどんな命名規則を選ぶだけでも言うでしょう。数年でJavaをやったことはありませんが、すべてのインタフェースはそれぞれ独自のディレクトリに置かれることになり、それが規約でした。本当に問題があったことはありません。

23
Matt Briggs

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

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

また、機能を定義するインタフェース(ComparableIterableなど)は、IComparableIIterableなどではなく、そのように名前を付けることをお勧めします。

6
David Koelle

良い[OOの原則に従って、あなたのコードは(実用的で可能な限り)具体的なクラスではなく抽象化に依存するべきです。例えば、一般にこのようなメソッドを書くのがより良いです。

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

これより:

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

この考えに従うならば、 "IUser"、 "UserInterface"、またはその他のバリエーションではなく、 "User"や "BankAccount"などのインターフェイス名を指定すると、コードの読みやすさが向上します。

実際の具象クラスを気にする必要があるのは、具象クラスが構築される場所だけです。他のすべてのものはインターフェースを使って書かれるべきです。

こうすると、 "UserImpl"のような "醜い"具象クラス名は、残りのコードから安全に隠されるはずです。これは、 "Nice"インターフェース名を使用してもうまくいくことがあります。

5
KarstenF

= v = "I"接頭辞はWicketフレームワークでも使われていて、そこで慣れました。一般的に、私は面倒なJavaクラス名を短くする規則を歓迎します。ディレクトリとJavadocでは、すべてが "I"の下にアルファベット順に並べられているのが面倒です。

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

"Impl"接尾辞は見苦しい略語で国際化がうまくいきません。少なくとも "Imp"を使用しただけであれば、それは可愛い(そしてもっと短い)でしょう。 "Impl"はIOC、特にSpringに使用されているので、私たちは今のところそれを使用しています。ただし、1つのコードベースの3つの異なる部分で3つの異なる規則に従うと、ちょっとしたことになります。

2
Jym Dyer

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

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

0
David Thornley