インターフェイス名は「I」プレフィックスで始まる必要がありますか?


73

私は、ロバート・マーティンによる「クリーン・コード」を読んで、できればより良いプログラマーになることを望んでいます。これまでのところ、どれも本当に画期的なものではありませんでしたが、アプリケーションの設計とコードの記述方法について、私は違った考え方をしました。

本の一部には、同意しないだけでなく、特にインターフェースの命名規則に関して、私には意味がありません。これは、本から直接取ったテキストです。混乱を招くと思われるこの側面を太字で示し、説明を希望します。

私はインターフェースを装飾しないままにしておきたい。前のIは、今日のレガシーワッドで非常に一般的であるが、せいぜい気を散らすものであり、最悪の場合には情報が多すぎる。ユーザーにインターフェースを渡していることをユーザーに知らせたくない

おそらく、私が学生だからか、プロやチームベースのプログラミングを一度もしたことがないからかもしれませんが、それがインターフェースであることをユーザーに知ってもらいたいからでしょう。 インターフェイスの実装とクラスの拡張には大きな違いがあります。

それで、私の質問は、「コードの一部がインターフェースを期待しているという事実を隠す必要があるのか​​?」に要約されます。

編集

回答に応じて:

タイプがインターフェースである場合、またはクラスがあなたのビジネスであり、コードを使用している誰かのビジネスではない場合。したがって、このサードパーティのコードでコードの詳細を漏らさないでください。

特定の型がインターフェイスであるか、サードパーティのコードのクラスであるかの詳細を「漏洩」しないのはなぜですか?サードパーティの開発者がコードを使用して、インターフェイスを実装するのか、クラスを拡張するのかを知ることは重要ではありませんか?違いは、私が自分の頭に浮かぶほど重要ではありませんか?


3
あなたの意見に同意します。情報の隠蔽が多すぎるとあまり役に立ちません。ただし、このガイドラインに従ったとしても、IDEまたはアドオンを使用してタイプを伝えることができます。
NoChance

3
この質問は基本的に「ハンガリー語表記」の質問として知られており、多くの議論と、MS以外のほとんどの開発者がこのキーワードでそれを放棄した理由を見つける必要があります。ハンガリー語の表記法は、ほとんどの場合変数で一般的ですが、型についても本質的に同じです。
チトン

2
以前のタイトル編集はひどいものでした。この質問は、ハンガリーの表記法に関するものではなく、単にそれに関連する可能性のある表記法に言及しているだけです。HNの相対的なメリットは、ここではまったく無関係です。質問は、具体的にはインターフェイスとクラス、およびセマンティックの違いが特別な場合の命名規則を正当化するのに十分に重要/興味深いかどうかに関するものでした。
アーロンノート

to know whether they will be implementing an interface or extending a class:はい、しかしあなたのコードのほとんどのユーザーはそれを呼び出し、それを実装したり拡張したりせず、彼らは本当にそれが何であるか気にしませんでした。
david.pfx 14

それが価値があるもののために、私は「I」プレフィックスを大いに好みます。同じ理由で、抽象クラスにも「Abstract」プレフィックスを使用します。クラス/インターフェースの消費者には違いはありませんが、そのインスタンスを提供する必要のある人に大きな違いをもたらすことができ、コードを読んでいる他の開発者にとってもはるかに簡単になります。つまり、詳細についてはケースバイケースでIDEに問い合わせる必要がなく、彼らが扱っているものが一目でわかるということです。私はAngularを使い始めたばかりで、彼らがこの慣習に従わないのは本当に迷惑です!
ダン・キング

回答:


67

それについて考えるのをやめた場合、インターフェイスは実際には抽象クラスと意味的にそれほど変わらないことがわかります。

  • 両方ともメソッドおよび/またはプロパティ(動作)があります。
  • どちらにも非プライベートフィールド(データ)がありません。
  • どちらも直接インスタンス化することはできません。
  • 1つから派生するとは、派生型も抽象でない限り、その抽象メソッドを実装することを意味します。

実際、クラスとインターフェイスの最も重要な違いは次のとおりです。

  • インターフェイスにプライベートデータを含めることはできません。
  • インターフェイスメンバはアクセス修飾子を持つことができません(すべてのメンバは「パブリック」です)。
  • クラスは複数のインターフェイスを実装できます(通常、1つの基本クラスのみから継承できるのに対して)。

クラスとインターフェースの唯一の特に意味のある違いは、(a)プライベートデータと(b)タイプ階層(どちらも呼び出し側にわずかな違いももたらさない)を中心に展開するため、通常、タイプがインターフェースであるか、クラス。もちろん、視覚的な表示は必要ありません。

ただし、注意すべき特定のコーナーケースがあります。特に、リフレクション、インターセプト、ダイナミックプロキシ/ミックスイン、バイトコードウィービング、コード生成、または環境のタイピングシステムまたはコード自体を直接操作することを伴うものを使用している場合は、すぐに知ることが非常に役立ち、時には必要ですインターフェースを扱うのかクラスを扱うのかに関係なく。インターフェースではなくクラスをミックスインとして追加しようとしたため、コードが不可解に失敗することは明らかに望ましくありません。

ただし、一般的な、バニラで、すぐに使えるビジネスロジックコードの場合、抽象クラスとインターフェイスの違いは、決して機能しないため、宣伝する必要はありません。

Iとにかく、Microsoftが使用および提唱している.NET規則であるため、とにかくC#インターフェイスのプレフィックスを付ける傾向があります。そして、新しい開発者にコーディング規則を説明するとき、Microsoftの規則を使用するだけで、独自の「特別な」規則がある理由を説明するよりもはるかに簡単です。


この内訳をありがとう。「クラスとインターフェースの意味のある区別...」のための+1
チャールズスプレーベリー

24
「これはすべて言われているが、Microsoftが使用し提唱している.NETの規則であるため、とにかくC#インターフェイスに接頭辞を付ける傾向がある」ための+1です。これは私にとってC#で十分な理由です。この共通の標準に従うことにより、他の.NETプログラマーがインターフェイスを識別する可能性が高くなります。
ロボット寿司

4
JavaとC#の両方を作成する人として、「これはすべて言われていますが、Microsoftが使用および提唱している.NET規約であるため、とにかくC#インターフェイスにプレフィックスを付ける傾向があります」-控えめに言えません私が働いている言語を覚えているのに役立ちます
アイドス

3
.NETのもう1つの違い(ただしJavaを除く)は、多くの.NET言語ではインターフェイスに静的メソッドを含めることができないため、インターフェイスをハッキングIするとクラスに適切な名前を付けて、インターフェイスに関連付けられた静的メソッドを保持できます(たとえば、Enumerable<T>.EmptyまたはComparer<T>.Default)。
supercat

懸念事項が1つあります。C ++では、ヘッダーを開いてclass Foo既に拡張されているclass Barことを確認した場合class Bar、拡張されているか実装されているかはすぐにはわかりません。そのため、class Barヘッダーを調べて、class Fooextend に変更するかどうかを判断する必要がありclass Bazます。さらに、接頭辞Iは、「単一の基本クラス」に違反しているかどうかを明確に視覚的に示すため、ヘッダーを開くたびに健全性チェックが行われます。
jsj

14

多くの点で、一貫性は慣例よりも重要です。命名スキームが一貫している限り、それらを扱うのは難しくありません。必要に応じてプレフィックスIを使用するか、名前をそのままにしておくか、スタイルを選択してそれを使用する限り、それは重要ではありません。


2
一貫性のために+1>規則。C#ではプレフィックスをIにしますが、Javaではプレフィックスを付けません。さまざまなタスクがさまざまな規則を必要としています
Bringer128

2
個人的にはインターフェイスにIsを使用したくないと思う一方で、.Netプロジェクトで使用されるBCLおよびサードパーティライブラリと矛盾することは、オプションではありません。
jk。

13

この本は良いものでいっぱいですが、インターフェイス名に「I」を追加します。

public interface ILogデフォルトの実装を使用していると想像してくださいpublic class Log

さて、持っていると決めたらpublic interface Log、突然Logクラスをpublic class LogDefaultそれらの行に変更する必要があります。キャラクターを1つ追加することから7つに変更しました-確かに無駄です。

多くの場合、理論と実践の間には細かい境界線があります。理論的にはこれは非常に良い考えですが、実際にはあまり良くありません。


これは、.NET用に記載されているドキュメント
levininja

30
「パブリックインターフェースILogにデフォルトの実装パブリッククラスLogがあることを想像してください。」-次に、デフォルトの実装の名前が貧弱です。何をLogするの?コンソールにログインしますか?syslogに?どこにも?それらは、それぞれConsoleLogSyslogLogおよびを呼び出す必要がありNullLogます。Log具体的な名前ではないため、具体的なクラスの名前としては適切ではありません。
セバスチャンレッド

7
個人的にこれがまさにITheClassNameを見るのが嫌いな理由です。理由もなくインターフェースを作成しているだけなのか、それはTheClassNameの上にあるだけのノイズなのでしょうか。インターフェイスに目的がある場合、ITheClassNameよりも良い名前を付けることができるはずです
リチャードティングル

クラスの名前は(インスタンス化するために)一度使用され、インターフェースの名前はどこでも使用されます。インターフェイスに文字を追加してクラス名の文字を保存することは、(文字の)誤った経済学です。
セルグート

@RichardTingleしかし、私はそこに一般的な使用法があると思うので、それMyClassモック可能なバリエーションを持っていますよね?つまり、インターフェイスを使用して、テストを可能にする方法で基本的にパブリックメソッドを実際にパブリックにします。(それは良いことでも悪いことでもありませんが、インターフェイスの動機は依存関係であるクラスを簡単にモックできるようにすることであることが多いことを理解すると、1対1のマッピングが説明さMyClassIMyClassます。)
ruffin

8

これは、インターフェイスの実装やクラスの拡張に関するものではありません。それらの場合、とにかくあなたは何をしているのかを知っています。

ただし、サードパーティコード(exempleのアプリケーションの別のモジュール)がデータを操作する場合、このコードは、インターフェイスまたはクラスを提示するかどうかを気にする必要はありません。

これが抽象化のポイントです。このサードパーティコードに、特定のタイプのオブジェクトを提示しています。この型には、呼び出すことができるメンバー関数があります。それで十分です。

タイプがインターフェースである場合、またはクラスがあなたのビジネスであり、コードを使用している誰かのビジネスではない場合。したがって、コードの詳細をこのサードパーティのコードに漏らさないでください。

ちなみに、インターフェイスとクラスは最後に参照型になります。そして、これが重要なことです。したがって、これが命名規則で強調する必要があるものです。


@Mat>はい、それは私の間違いでした。編集しました。
-deadalnix

5

ほとんどの答えは、プログラミング言語がJavaまたはC#であり、インターフェイス/抽象クラスの概念(またはキーワード)があると仮定しているようです。これらの場合、まともなIDEでは、どのタイプのクラス1が対処するのかがすぐにわかり、書き込みpublic interface IMyClassは不必要な複製です。あなたが書かないようなものですpublic final FinalMyClass-クラス名にすべてのキーワードを入れることを想像してください。

ただし、C ++での私の意見では、状況は少し異なります。ヘッダーファイルに飛び込んで、クラスに抽象クラスかどうかを確認する仮想メソッドがあるかどうかを確認する必要があるためです。その場合、私は書くことについての議論を明確に見ることができclass AbstractMyClassます。

私の答えは、プログラミング言語に依存します。

2016年更新: 2年後のC ++の経験おそらくクラス名の前にを付けるのは悪い習慣Abstractだと思いますが、おそらく理にかなっているほど複雑なコードベースがあると思います。


これで質問に答えますか?他の回答を読んで、いくつかのポイントを明確にしたいかもしれません。
david.pfx 14

C ++には、キーワードがなくても、間違いなくインターフェイスがあります。すべてのメンバー関数が純粋仮想であり、メンバー変数がないクラスを何と呼びますか?

@ david.pfx:「インターフェイス名は「I」プレフィックスで始まるべきですか?」という質問に正確に答えていると思います:プログラミング言語に依存します。あなたが私の精緻化が十分に明確でないと思われる場合、私はそれを改善させていただきます-あなたにとってどの部分が明確ではありませんか?
Ela782 14

2
@JohnGaughan:確かにインターフェースがあります!しかし、私の全体的なポイントは、キーワードに関することです。C ++にはそれがないため、IDE /ユーザーがインターフェイスを扱うかどうか見えません。ただし、Javaでは、すぐに表示されます。
Ela782 14

1
一流の回答を読んで、あなたと比較してください。あなたはSOに不慣れであり、これはどのような答えが投票を引き付けるかを学ぶ機会です。現状では、そうではありません。より多くの作業、より多くの説明、より多くの価値があれば、それはただかもしれません。頑張れ!
david.pfx

4

使用している言語のイディオムに従ってください。

各言語には独自のイディオムとコーディングガイドラインがあります。たとえば、C#では、インターフェイスの先頭にIを付けるのが慣用的です。Goでは、そうではありません。


+1使用している言語のイディオムに従ってください。本書の著者は明らかにJava開発者です。.NET / C#:ILog Java:Logしかしデメリット:ILogインターフェイスを実装するLogクラスが必要な場合.... MyLog、LogDefault、LogBase、...?glyいですね。もっとい:LogImpl ....:D
hfrmobile

0

私の(Java)コードでは、呼び出し元に公開するAPIでこの規則を使用する傾向があります。

  • 機能はインターフェースを通じて提供され、クラスによって提供されることはありません
  • 非機能部分はクラスです。

機能しないということは、純粋なデータ構造(XMLシリアル化またはORMへのブリッジとして機能するクラスなど)、列挙、例外などを意味します。これらはすべてインターフェイスにはなれません(まあ、純粋なデータクラスには、ただし、データ保持する以外にこれらのクラスが行うことはないため、非常にわずかな利益で多くの作業が行われます)。

命名規則の観点から、インターフェースはアクター名詞(例FooBarWatcher)または形容詞(例)にマップする傾向がFooBarWatchableあり、純粋なデータクラスと列挙の両方が非アクティブ名詞(例FooBarStatus)にマップされます。IDEは、特別な命名規則なしでAPIコンシューマーをガイドできます。例外は、(通常のJavaの規則に従ってくださいFooBarExceptionFooBarErrorFooBarFaultもちろん)。

また、自分のルールを破ろうとしないようにするために、インターフェイスを独自のパッケージまたは独自のライブラリに入れることもよくあります。(これは、WSDLドキュメントなどの外部ソースからコードを導出するときに、ビルドを管理するのにも役立ちます。)


またI、インターフェイスにはプレフィックスを付けません。もちろん、それはインターフェースです!API(またはSPI)にあります!
ドナルドフェローズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.