タイトルはそれ自体を物語っていると思います-そのインターフェイスの具体的な実装が1つしかないのに、なぜインターフェイスを作成してから具体的なクラスを実装する必要があるのでしょうか?
11 に答える
私はあなたがすべきではないと思います;)
すべてのクラスを対応するインターフェースでシャドウする必要はありません。
後でさらに実装を行う場合でも、必要になったときにいつでもインターフェイスを抽出できます。
これは粒度の問題です。不要なインターフェースでコードを乱雑にすることはできませんが、それらはレイヤー間の境界で役立ちます。
いつか、このインターフェースに依存するクラスをテストしようとするかもしれません。それから、それを嘲笑できるのはいいことです。
私は常にインターフェイスを作成および削除しています。努力する価値のないものもあれば、本当に必要なものもあります。私の直感はほぼ正しいですが、いくつかのリファクタリングが必要です。
問題は、具体的な実装が 1 つしかない場合、インターフェイスが必要かどうかです。
YAGNI-ウィキペディアからあなたはそれを必要としないだろう
YAGNIのアプローチを提唱する人々によると、現時点では必要ではないが将来的には必要になる可能性のあるコードを書きたいという誘惑には、次のような欠点があります。
* The time spent is taken from adding, testing or improving necessary functionality.
* The new features must be debugged, documented, and supported.
* Any new feature imposes constraints on what can be done in the future, so an unnecessary feature now may prevent implementing a necessary feature later.
* Until the feature is actually needed, it is difficult to fully define what it should do and to test it. If the new feature is not properly defined and tested, it may not work right, even if it eventually is needed.
* It leads to code bloat; the software becomes larger and more complicated.
* Unless there are specifications and some kind of revision control, the feature may not be known to programmers who could make use of it.
* Adding the new feature may suggest other new features. If these new features are implemented as well, this may result in a snowball effect towards creeping featurism.
まだ誰も言及していないことの 1 つは、依存関係の問題を回避するために必要な場合があるということです。依存関係がほとんどない共通プロジェクトにインターフェイスを配置し、依存関係が多い別のプロジェクトに実装を配置できます。
コードの作成には、テスト駆動型アプローチを使用します。これにより、多くの場合、テスト フィクスチャの一部としてモックまたはダミーの実装を提供するインターフェイスを作成することになります。
テストに何らかの関連性がない限り、通常はコードを作成しません。インターフェイスを簡単にテストすることはできず、実装のみをテストするため、テスト ケースの依存関係を提供するときにインターフェイスが必要な場合はインターフェイスを作成します。
また、重複を削除したりコードの読みやすさを改善したりするために、リファクタリング時にインターフェイスを作成することもあります。
後で必要になった場合は、いつでもコードをリファクタリングしてインターフェイスを導入できます。
これに対する唯一の例外は、サード パーティにリリースする API を設計している場合 (API の変更にかかるコストが高い場合) です。この場合、将来行う必要がある可能性のある変更の種類を予測し、将来の互換性のない変更を最小限に抑えるために API を作成する方法を見つけようとします。
あなたの質問に対する2つのやや矛盾する答え:
- 構築するすべての具象クラスからインターフェイスを抽出する必要はありません。
- ほとんどの Java プログラマーは、必要な数のインターフェースを構築していません。
ほとんどのシステム (「使い捨てコード」でさえも) は、当初の設計が意図したものをはるかに超えて進化し、変化します。インターフェイスは、結合を減らすことで柔軟に成長するのに役立ちます。一般に、インターフェイスにコーディングする必要がある警告サインは次のとおりです。
- 別の具象クラスが同じインターフェースを必要とするのではないかと疑っていますか?
- コードが Web サービス レイヤーの反対側に存在する必要があると思われますか?
- あなたのコードは外部クライアントへのサービス層を形成していますか?
これらすべての質問に正直に「いいえ」と答えることができる場合、インターフェースはやり過ぎかもしれません。そうかもしれない。しかし、繰り返しますが、予期せぬ結果はプログラミングにおけるゲームの名前です。
パブリック関数を指定して、プログラミング インターフェイスを決定する必要があります。そこをしっかりやらないと使いにくいクラスです。
したがって、後で正式なインターフェイスを作成する必要があると判断した場合は、設計を準備しておく必要があります。
したがって、インターフェイスを設計する必要はありますが、インターフェイスとして記述して実装する必要はありません。
これの多くは、InfoQに関するRainsbergerの講演から引用されています:http://www.infoq.com/presentations/integration-tests-scam
クラスを持つ理由は3つあります。
- それはいくつかの価値を持っています
- それはいくつかのエンティティを永続化するのに役立ちます
- それはいくつかのサービスを実行します
大部分のサービスにはインターフェースが必要です。それは境界を作成し、実装を隠します、そしてあなたはすでに2番目のクライアントを持っています。そのサービスと相互作用するすべてのテスト。
基本的に、単体テストでモックアウトしたい場合は、インターフェースが必要です。
「これまでに1つの実装しかありません」==有名な最後の言葉
インターフェイスを作成し、そこから具体的なクラスを派生させるのにそれほど費用はかかりません。それを行うプロセスは、デザインを再考させる可能性があり、多くの場合、より良い最終製品につながります。そして、一度それをやったら、あなたがそれらの言葉を食べていることに気付いた場合-頻繁に起こるように-あなたはそれについて心配する必要はありません。すでに設定されています。それ以外の場合は、リファクタリングを行う必要があり、それは苦痛になります。
明確にするために編集:私は、このクラスが比較的広範囲に広がることを想定して取り組んでいます。それが単一のパッケージ内の他の1つまたは2つのクラスによって使用される小さなユーティリティクラスである場合は、そうです、心配しないでください。それが他の複数のクラスによって複数のパッケージで使用される予定のクラスである場合、私の前の答えが当てはまります。
質問は次のとおりです。
どうすれば完全に確信できますか?
これを熟考した時点で、すでにインターフェイスを作成しており、間違っていることが判明する可能性のある仮定をせずに進んでいるはずです。
今日のコーディング ツール (Resharper など) を使用すると、クラスと一緒にインターフェイスを作成して維持するのにそれほど時間はかかりませんが、追加の実装が必要であり、すべての具体的な参照を置き換えることが必要であることを発見するには、長い時間がかかります。まったく面白くありません-信じてください。