私は、うまくいけば、より良いプログラマーになるために、ロバート・マーティンによる " Clean Code "を読んでいます。これまでのところ、どれも本当に画期的なものではありませんが、アプリケーションの設計とコードの記述方法について、私は別の考えを抱かせました。
この本には、私が同意しないだけでなく、特にインターフェースの命名規則に関して、私にとって意味のない部分があります。これは本から直接取ったテキストです。私は混乱を招くこの点を大胆に説明しました。
私はインターフェースを飾り気のないままにしておくことを好みます。先行するIは、今日のレガシーワードで一般的ですが、せいぜい気晴らしであり、最悪では情報が多すぎます。 ユーザーにインターフェースを渡していることをユーザーに知られたくない。
たぶん私は学生だからか、プロやチームベースのプログラミングをしたことがないからかもしれませんが、それがインターフェイスであることをユーザーに知らせたいと思います。インターフェースの実装とクラスの拡張の大きな違い。
つまり、私の質問は「コードの一部がインターフェイスを想定しているという事実を隠す必要があるのはなぜですか?」
編集
答えに応じて:
タイプがインターフェースであるか、クラスがビジネスである場合、コードを使用する誰かのビジネスではありません。したがって、このサードパーティのコードでコードの詳細を漏らすべきではありません。
指定された型がサードパーティのコードへのインターフェイスまたはクラスであるかどうかの詳細を「漏らさない」必要があるのはなぜですか?サードパーティの開発者が自分のコードを使用して、インターフェイスを実装するのか、クラスを拡張するのかを知ることは重要ではありませんか?違いは、私がそれらを私の心の中にあるようにするために作っているほど重要ではないのですか?
それについて考えるのをやめると、インターフェイスは抽象クラスと意味的にあまり変わらないことがわかります。
実際、クラスとインターフェースの最も重要な違いは次のとおりです。
クラスとインターフェイスの唯一の特に意味のある違いは、(a)プライベートデータと(b)タイプ階層を中心に展開されるため、どちらも呼び出し元にわずかな違いを生じないため、通常、タイプがインターフェイスであるか、それともインターフェイスであるかを知る必要はありません。クラス。あなたは確かにvisual表示を必要としません。
ただし、注意すべき特定のコーナーケースがあります。特に、リフレクション、インターセプト、ダイナミックプロキシ/ミックスイン、バイトコードウィービング、コード生成、または環境の直接への干渉を伴うものを使用している場合システムまたはコード自体を入力する-それは非常に便利であり、インターフェイスとクラスのどちらを扱っているかをすぐに知る必要がある場合があります。インターフェースではなくクラスをミックスインとして追加しようとしたため、コードが不思議なほど失敗することは望ましくありません。
ただし、一般的なバニラのありふれたビジネスロジックコードの場合、抽象クラスとインターフェイスの違いは、実際に使用されることはないため、宣伝する必要はありません。
これがすべて言われているとはいえ、とにかく、C#インターフェイスにI
をプレフィックスとして付ける傾向があります。また、コーディング規約を新しい開発者に説明するときは、Microsoftのルールを使用するほうが、独自の「特別な」ルールがある理由を説明するよりもはるかに簡単です。
多くの点で、一貫性は慣習よりも重要です。命名体系に一貫性がある限り、それらを操作するのは難しくありません。必要に応じて、Iでインターフェースの接頭辞を付けるか、名前をそのままにしておきます。スタイルを選択してそれに固執する限り、私には関係ありません。
この本は良いものでいっぱいですが、私はまだインターフェイス名に「I」を追加します。
public interface ILog
があり、デフォルトの実装public class Log
があるとします。
ここで、public interface Log
を使用することにした場合、突然、Logクラスをpublic class LogDefault
またはこれらの行の何かに変更する必要があります。あなたは1つの余分なキャラクターを持つことから7つになりました-それは確かに無駄です。
多くの場合、理論と実践の間には細かい境界があります。理論的にはこれは本当に良い考えですが、実際にはそれほど良くありません。
これは、インターフェースの実装やクラスの拡張に関するものではありません。それらのケースでは、あなたはとにかくあなたが何をしているのか知っています。
ただし、サードパーティのコード(たとえば、アプリケーションの別のモジュール)がデータを操作する場合、このコードは、インターフェイスとクラスのどちらを表示するかを気にする必要はありません。
これが抽象化の要点です。このサードパーティのコードに、特定のタイプのオブジェクトを提示しています。この特定の型には、呼び出すことができるいくつかのメンバー関数があります。もういい。
タイプがインターフェースであるか、クラスがビジネスである場合、コードを使用する誰かのビジネスではありません。したがって、コードの詳細をこのサードパーティのコードに漏らすべきではありません。
ちなみに、インターフェースとクラスは最後に参照型です。そして、これが重要です。だから、これはあなたの命名規則が強調しなければならないことです。
ほとんどの回答は、プログラミング言語がJavaまたはインターフェイスまたは抽象クラスの概念(またはキーワード)があるC#のいずれか)であると想定しているようです。これらの場合、適切なIDEでは、扱うクラスのタイプで表示され、public interface IMyClass
は不必要な重複です。 public final FinalMyClass
-すべてのキーワードをクラス名に含めることを想像してください。
ただし、C++での私の意見では、ヘッダーファイルに飛び込んでクラスに抽象クラスであるかどうかを確認する仮想メソッドがあるかどうかを確認する必要があるため、状況は少し異なります。その場合、class AbstractMyClass
。
だから私の答えは:それはプログラミング言語に依存します。
2016年の更新: 2年後のC++の経験おそらく、クラス名の前にAbstract
を付けることはおそらく悪い習慣だと考えますが、非常に複雑なコードベースがあると思いますそれは理にかなっているかもしれません。
使用している言語の慣用句に従ってください。
各言語には独自のイディオムとコーディングガイドラインがあります。たとえば、C#では、インターフェイスの前にIを付けるのが慣用的です。Goではそうではありません。
私の(Java)コードでは、呼び出し元に公開するAPIでこの規則を使用する傾向があります。
非機能的とは、純粋なデータ構造(XMLシリアル化またはORMへの橋渡しとして機能するクラスなど)、列挙、および例外のようなものを意味します。これらすべては、ca n'tはインターフェースです(まあ、純粋なデータクラスの場合は可能ですが、これらのクラスが実行することは何もないため、ほとんど利益が得られませんexceptデータを保持します)。
命名規則に関して、インターフェースはアクター名詞(例:FooBarWatcher
)または形容詞(例:FooBarWatchable
)にマップする傾向があり、純粋なデータクラスと列挙型の両方が非アクティブ名詞(例:FooBarStatus
); IDEは、特別な命名規則なしでAPIコンシューマをガイドできます。例外は通常どおりですJava規則(FooBarException
、FooBarError
、 FooBarFault
)もちろんです。
また、インターフェイスを独自のパッケージまたはライブラリに配置することもよくあります。これは、自分のルールに違反しないようにするためです。 (これはまた、WSDLドキュメントなどの外部ソースからコードを派生させるときに、ビルドを管理するのにも役立ちます。)