私が働いている会社では、すべてのサービスクラスに対応するインターフェイスがあります。
これは必要ですか?
ノート:
具象クラスをモックできる最新のモックライブラリと、2回程度のクリックでクラスからインターフェイスを抽出できるIDEを使用すると、これは以前の時代からの引き継ぎにすぎませんか?
あなたの会社はSOLID=の原則に従っており、具体的なクラスではなくインターフェースをターゲットにすると、プログラムにオーバーヘッドが追加されなくなります。彼らがしていることは、ボリュームを返済できる非常に適度な追加作業です。あなたがしている仮定は最終的には間違っています...そしてそれがどのような仮定になるかは決してわかりません。あなたが推奨することは少し作業が少ないのですが、リファクタリングに何時間も多くの時間を費やす可能性があります基本的なOO設計原則に従ってください。
あなたはこれらの人から学び、自分を幸運だと考えるべきです。しっかりとしたデザインを優先目標とするこのような環境で仕事をしたいと思います。
あなたの質問を考えると、この種の設計の理由は文書化されていないと思います。
[〜#〜] yagni [〜#〜] に違反しているため、単一実装のインターフェースの不正な使用は明らかに間違っています。私の経験では、これはまた、主にインターフェイスを実装するメソッドが不必要にパブリックにされることを余儀なくされているため、メンテナンス面でかなり有害です。さらに多くの リファクタリング エクスペリエンスを収集した後、privateおよびpackage privateアクセス修飾子の控えめな魅力を認めることができるようになります単一のクラス/パッケージ内で注目を集める。
文書化されていないこのイディオムの正当な使用法については、それは私の目にはまずい-とにかくメンテナが「悪いことから良いことを伝える」ことができないからです。その結果、これはあまり魅力的でないオプションの間に1つを残します。オプションは、疑わしいパブリックなものを現状のまま維持することにより、繰り返しコードを変更する必要があるたびに生産性を低下させるか、単一の実装を盲目的に「折りたたむ」ことでリスクのある変更を行い、保守を容易にすることです。 [〜#〜] pojo [〜#〜] -自分をリスクにさらし、これが間違った方法であることを痛感すること、他のいくつかのこと(神は禁ずる remote )モジュールあなたの視界の外はインターフェースを期待しています。
私は、単一実装インターフェースの誤った崩壊によって引き起こされた「啓示」を何度か経験しました。毎回それは教育的な経験でしたが、私は本当に再びそこに行きたくありません。ことは、これはテストの後半、統合時、またはユーザーの受け入れ時に発生し、この段階でのずっと前の間違いをロールバック/修正するのは非常に面倒です。
私は実用性を見ることができませんでした...インターフェイスは
com.company.service.foo
とcom.company.service.foo.impl
のように1対1で使用されます
以下は、私がそのようなケースを通常どのように処理するかについてです。
PRJ-123
文書化されていない、Foo/FooImplでの単一の実装によるインターフェースの不審な使用法)。誰かが説明しに来た場合に備えて、しばらく待ってください。 少なくとも一週間か二週間待ちます
Foo
にjavadocsを追加しますpurpose PRIF-123で説明されているインターフェースの目的c)閉じるチケット、d)次の3つのステップをスキップします。PRJ-123
)の結果に基づいて、残りの同様のケースに対処するために、新しい課題追跡チケットを作成して処理します。目的を文書化するか、POJOに折りたたみます。Adam Bien この質問について考えてみましょう: Service s = new ServiceImpl()-なぜあなたはそれをしているのですか?
これは肥大化するだけでなく(「Convention Over Configuration」の考え方とは逆です)、実際にダメージを与えます。
- 別の実装を取得すると想像してみてください(それがインターフェースの要点です)-どのように名前を付けますか?
- アーティファクトの量が2倍になり、「複雑さ」が大幅に増加します。
- インターフェースとインプリでjavadocを読むのは本当に面白いです-別の冗長性
- IDEのナビゲーションは流暢ではありません
そして私は彼に同意します。
おそらくあなたの同僚はJ2EEに遅れをとっています。これはJ2EEで作業するときに必要だったため、おそらくJ2EEの困難な時期に関する古いチュートリアルをインターネットで見つけることができます。
Javaインターフェースはモック性だけではありません(もちろん、それが要因です)。インターフェイスは、プライベートメソッドや属性などの実装の詳細なしで、サービスのパブリックコントラクトを公開します。
(あなたの場合のように)内部サービスを使用する場合の「パブリック」とは、他のプログラマーや内部サービスを含む(ただしこれらに限定されない)上記のサービスの実際のユーザーを指します。
すべてのサービスクラスにインターフェースがある理由の1つとして、洗練されたフレームワーク(Spring、JEEなど)とのやり取りがはるかに簡単になることが考えられます。これは、Javaがインターフェイスに対してインターセプターオブジェクトを単に生成できるためです(Java.lang.reflect.Proxy
);具象クラスに対してそうすることははるかにトリッキーであり、複数の異なるクラスローダーを使用する場合、いくつかの非自明な警告で満たされます。これは、OSGiを使用する場合にも当てはまります。OSGiを使用すると、これらのサービスインターフェイスは、それらのサービスの実装とは異なるクラスローダーからロードされます。これにより(サービスディスカバリファブリックと合わせて)、各サービスとそのクライアントの間に非常に強力な分離が適用されます。クライアントは文字通りできない抽象化を壊します。
IDEが1回のクリックでクラスからインターフェイスを抽出できる場合でも、必ずしも正しいインターフェイスを抽出するわけではないことに注意してください。知性はまだ必要です。
インターフェースを最初に使用するとオーバーヘッドのように見えますが、後で機能を拡張する必要があるときに、これらのインターフェースが非常に役立ちます。
具体的な実装のみを行う場合は、コードの実装を大幅に変更する必要があります。ただし、インターフェースを使用する場合は、インターフェースの規約を実装する新しいクラスを1つ追加するだけです(また、古いインターフェースの参照変数から新しいクラスオブジェクトを呼び出すことができます)。 。