どこでもインターフェース? - ベストプラクティス

OOPでインターフェースを正しく使用することについて、作業中の議論があります。私は、インターフェースは具体化の前にあり、すべてのメソッドは契約を扱うべきであると教えられ、そして常に前提から働きました。これは101とデカップリングしています。

私はこのパターンを適用することで普遍的にジュニアの開発者にロープを教え、成功への道を切り開いてくれました(「おお、これは密接に結びついています。私はこれを使うことができません!」)。 。我々は常に、常に契約を扱うことを理解するのは簡単です(そして価値があります)。

もう1人の仲間は、抽象化は複数の実装がある場合にのみ適用されるべきであり、それを常に行うことはチームを混乱させるものになると言っています。私にとっては、私は気にしません; D最初は混乱するだけで、すぐに2番目の性質になります。

しかし、私は手を差し伸べて、誰かがなぜそうでないのかを説明するいくつかの参考文献/専門家のテキストを提供できるかどうかを見たかったのです。

2
私は「抽象化」はソフトウェア工学においていくつかの異なる意味を持つと思います。私にとって、インターフェースは抽象化とは関係ありません。抽象化は実装の詳細とは関係ありません。それはデザインと関係があります。概念化あなたがインターフェースの有無にかかわらず達成することができる何か。
追加された 著者 glacier,
単一のクラスからインターフェースを作成することの主な危険は、あなたがそれをひどく間違ってしまうことです。古代オーストラリア人がIMammalのインターフェースを定義したと想像してみてください。彼らはすべて必要な sizeOfPouch()メソッドを持っているでしょう...
追加された 著者 MrG,
Yが抽象クラスから恩恵を受ける理由を正確に説明してください。抽象化はまったく同じですか?コードは変わりません。クラスもコンストラクタを提供する必要がないことを念頭に置いて、何百もの場所でコンストラクタ呼び出しがありますか?依存性注入はC#やJavaよりはるかに古いです。
追加された 著者 Frank Hileman,
あなたの論理はわかりません。 APIが同一の場合、インタフェース、具象クラス、抽象クラスの使用に関係なく、スワップはシームレスです。唯一の違いは構造です。これは、DIだけではなく、さまざまな方法で分離できます。
追加された 著者 Frank Hileman,
InterfaceBは、同じプロセス内で両方のサービスを同時に使用する場合(多重継承)にのみ価値を提供します。しかし、基本クラスを使用することでその利点を得ることもできます。
追加された 著者 Frank Hileman,
ある型を別の型に置き換える場合は、基本クラスを使用するか、元の型を変更します。どんなOO言語でもうまくいくでしょう。あなたはあなたがどちらかのタイプを同時に必要としているか、コンポーネントを作成している異なる組織(プラグイン)があるという状況を説明しています。
追加された 著者 Frank Hileman,
あなたはこの主張について説明していません。私はユーザーの観点からあなたに言っているのですが、インターフェース(専門クラス)とクラスの唯一の違いはコンストラクタです。これを修正するには何百万ドルもかかる例を挙げなければなりません。
追加された 著者 Frank Hileman,
一般に、高価な変更は型の名前の変更ではなく、APIの侵襲的な変更です。 DIとインターフェースは役に立ちません。あなたのシナリオは仕事を節約することとは無関係です。
追加された 著者 Frank Hileman,
余計なインターフェースを削除するのに長い時間を費やしてきたので、私はそれをカーゴカルトデザインと名付けました。唯一の利点は、ソフトウェアを開発するためのコストを増やすことです。請負業者や従業員にはおそらくいいのですが、開発にお金を払う人にはいいのです。
追加された 著者 Frank Hileman,
@froodley正しいですが、そのような言語のクラスは抽象化(提供される操作)と1つのテキスト文書への実装の両方です。すなわち一方、他の言語ではそれらは別々になっている場合がありますが、そのような言語ではそれらを1つの単位にまとめることができます。それらはまだ分離することができます...クラスは未実装のメンバーを残すことができます。すべてがそうであるならば、それは多重継承の利点なしで、インターフェースと同等です。
追加された 著者 Frank Hileman,
あなたが暗示する言語の種類におけるクラスは、その抽象化の抽象化と実装の両方です。クラスは「インターフェース」(API)を提供します。 interfaceキーワードを使用すると、言語の制限を回避するために、実装なしでクラスを指定できます。ユーザーの観点からは、クラスもインターフェースも他よりも優れているわけでも抽象的なものでもありません。インタフェースは構築をより困難にするかもしれません。
追加された 著者 Frank Hileman,
あなたがコンピュータサイエンス一般で使われているのと同じ用語を使っていないようです。クラスは抽象化であり、整数でも浮動小数点数でも抽象化です。インタフェースは「抽象化」を向上させません。より抽象的なデータ型はより一般的で型階層がより高いものです。実装の場所は抽象化の観点からは無関係です。
追加された 著者 Frank Hileman,
@ Meo私は同意します、そのような言語のインターフェースは多重継承のためだけのものです。しかし、私は質問の中で「抽象化」の誤用を好まない。
追加された 著者 Frank Hileman,
元の記事の「デカップリング101」に関しては、クラス1:1のパブリックメンバーに一致するインターフェースは、1つの実装しかない(つまり、単一のクラスに結合されている)ため、何もデカップリングしません。公開署名を変更するときは、両方を同時に更新する必要があります。同時に、結合すべきものを分離することに利点はありません。分離は、結合が問題となる状況での使用です。余分なインターフェースは貨物カルトデザインの一種です。
追加された 著者 Frank Hileman,
@froodleyコンストラクタはクラスによってのみ提供されますが、クラスもそれを提供する必要はありません。パブリックコンストラクタを持たないクラスは "concrete"ですか?ユーザーは実装がどこにあるのか気にしません。それらは抽象化だけで動作します。
追加された 著者 Frank Hileman,
@froodley「コンクリート」とはどういう意味ですか?コンピュータサイエンス、抽象データ型、抽象化レベルの用語は、JavaおよびC#のキーワード「abstract」とは関係ありません。このキーワードは、「未実装」またはクラスが「未完」の場合に適しています。あなたはコンストラクタを提供するデータ型を意味しますか?抽象化は、より正式には一連の操作およびそれらの操作のセマンティクスです。私たちが話す言語では、私たちはドキュメンテーションの中で意味論を指定することしかできません。すべてのデータ型は抽象化されています - 実装はユーザーによって考慮されません。
追加された 著者 Frank Hileman,
ソフトウェア設計用語の「インタフェース」と「具体化」をJava/C#の「インタフェース」と「クラス」と混同していませんか。実際には別のJava interface を書かなくても、インタフェースにプログラムすることができます。
追加された 著者 immibis,
具体的なクラスが抽象的であることに同意しません。あなたはそれがコンピュータコードの一部であり、実際には自動車ではないという意味であなたは意味しますか?私は抽象的なものを純粋に抽象的に扱うべきという意味での抽象化について言及しています。純粋に抽象クラス以外のものは、抽象概念ではなくなりました。ただし、それは実際にはCarではないという意味でのものです。
追加された 著者 Dave Lau,
抽象化は、定義上、実装になることはできません。
追加された 著者 Dave Lau,
代替案:サービスXはどこにでも直接注入されます。それはもうまったく機能しません。川下の消費者は、他の会社で、会社を辞めた開発者によって開発されたソフトウェアで、変更する必要があります。
追加された 著者 Dave Lau,
繰り返しますが、あなたが何年も費やしたことがあり、何百万人もが誰かのYAGNIスロッププログラミングに取り組むのであれば、あなたはなぜ私が同意しないのかを見ることができます。
追加された 著者 Dave Lau,
貨物カルトに関しては、私はそれが目的を果たさないことに本当に同意しません。特定の実装ではなく抽象化を正しく扱っていること、そしてハードコーディングではなくURLを構成可能にすることは、おそらく変更されないので、大変なことだと思います。
追加された 著者 Dave Lau,
あなたのソフトウェアが密結合されていると宣言されたことを間違った終わりにしたことがあり、それが分離するのに何百万もの費用がかかるであろうと、あなたは私が密結合ソフトウェアを開発することを拒否すると理解するでしょう。 1つの実装しかなくても、インタフェースを扱うことでソフトウェアを確実に分離できます。あなたのライブラリを、同じインターフェースを提供する独自の実装の上に実装またはファサードを提供する別のものに置き換えることができます。私はあなたがどこから来たのか本当にわかりません。それはすべてナマケモノのように思われ、私には拍手がかかる。
追加された 著者 Dave Lau,
コンピュータ内のすべてのものは抽象化です。
追加された 著者 Dave Lau,
定義上、インターフェースは具象クラスより抽象的です。
追加された 著者 Dave Lau,
それは、その概念表現の特定の実装ではなく、オブジェクトの概念表現です。
追加された 著者 Dave Lau,
私があなたに私にServiceXオブジェクトを与えなければならないと言うならば、私はあなたにServiceYオブジェクトを与えることはできません。コンパイラはそれを防ぎます。私があなたに私にInterfaceBオブジェクトを与えなければならないと言うなら、あなたは私にどちらか一方を与えることができます。
追加された 著者 Dave Lau,
今では何十もの消費者がいる図書館を交換する時が来たとき、それは当初コストを些細に増やしながら数百万ドルを節約する。
追加された 著者 Dave Lau,
あるタイプを別のタイプに置き換える場合、私はconfigでインジェクタを提供するファクトリ以外の何も変更しません。それはinterfaceBを実装する別のクラスをスピンアップし、コードはまったく変更されません。
追加された 著者 Dave Lau,
バックエンドシステムが置き換えられたため、サービスXは非推奨になりました。サービスYは、同じ目的を果たすために作成されています。私たちは依存性インジェクタにサービスZを提供しています、そしてインターフェイスBを満たすサービスだけを期待している複数のライブラリとアプリケーションにわたる子供たちは全く影響を受けません。
追加された 著者 Dave Lau,
あなたはどの言語で働いていますか?厳密に型指定された言語では、ServiceXを必要とするクラスにServiceYを挿入することはできません。
追加された 著者 Dave Lau,
私たちはサービスを提供しますY *
追加された 著者 Dave Lau,
@FrankHileman正確には、OPは基本的に1つの実装に対して2つのインタフェースを作成します。2つ以上の実装に対しては1つのインタフェースです。
追加された 著者 Michael,
@froodleyの言葉遣いはしますか?
追加された 著者 Michael,

5 答え

私は私がインターフェースを使っているかどうかさえ知りたくありません(キーワードkind)。私の運転機能は車です。それが具体的かどうかは、その事業のどれでもありません。

これが、私がC#の ICar 規約に苛立つ理由です。無意味なのノイズが私の顔からはみ出します。 Javaはそれほど良くありません。もちろん、慣例により、私はソースコードの中でインターフェース、抽象クラス、または具象クラスを Car と名付けることができますが、あるものから別のものに変更した場合、それを使うすべてを再コンパイルする必要があります!

欲しいのは、typeシステムに drive()のニーズが何であるかを表現することだけです。私が drive()に何を話しているのかを知りたいという気持ちはありません。

ちなみに、もしあなたが良いテストをしているのなら、アヒルタイピングのある言語はあなたにこれらすべてを無料で提供します。

しかし、これらの言語を使用する必要があるので、使用する傾向があります。 = "noreferrer">ロールインターフェースつまり、ドライブ(自動車)を書かない私はドライブ(DriverControls driverControls)を書いて、上のステアリング、加速、およびメッセージの中断を受け入れたいものは何でもDriverControlsプロトコルは自由にできます。

それで、それがあなたが話していることであれば私はあなたと一緒です。あなたが Car のようなすべてのクラスに ICar の対応物を持っていると主張する狂信者の一人であれば、湖でジャンプすることができます。

6
追加された
Javaでは、DriverControlsインターフェースは通常Drivableという名前になります。
追加された 著者 Alexei,
@froodleyは同意した。つまり、具体的なクラスを最初に使用した後でそれらをインターフェイスにリファクタリングするときに発生する可能性がある問題についての真の議論が必要です。これを実行し、オープンクローズド原則を尊重することは困難です。さらに悪いことに、 Car の具体的なステータスの認識が広がるのは簡単なことです。私は具体的なここに留まりながら、それを阻止しようと試みました。それはきれいではありません。
追加された 著者 candied_orange,
基本的にあなたが与えた理由のために、私はそうです。私は、ある特定の方法で物事を行う自動車という特定のことをしたくありません。私にとっては、これは一度限りのゴミコードです。契約とのやり取りをしたいのですが。私は.drive()と.steer()について知っていることを知っていて、文字列を返してくれるので、車かボートかを知る必要はありません。
追加された 著者 Dave Lau,

あなたはパズルの一つの大きな部分を見逃しています:

いたるところでインターフェースを使用すると、コードを操作しにくくなります。

長年にわたって成長してきた何百ものクラスを持つ大規模なコードベースがあるとします。

通常、メソッド内で何が起こるのかを知りたいときは、それをクリックするだけでIDEはそのコードにジャンプします。つまり、クラスの場合です。それがインターフェースの場合は、そのインターフェースにジャンプして、どのクラスがインスタンス化されているのかを把握する必要があります。これにはしばらく時間がかかります。実際にインスタンス化されたもの、しばらく時間がかかるものなどをもう一度把握する必要があります。

基本的に、コードをナビゲートすることは余分なインターフェースのためにますますイライラするようになります。

私の経験則:あなたが実際にその背後に複数の異なる実装があるときはインターフェースを使用します。


編集:

私の「はるかに難しい」はおそらく誇張されていました。私は単に「もっと難しい」または「わかりにくい」と書くべきです。

これを説明するために、日食で。クラスからのメソッドで:

  • Ctrl +クリックでメソッド内をジャンプします(1クリック)。

インターフェースからのメソッドでは、次のようになります。

  • Ctrl +クリック
  • 上に移動
  • インターフェイス名を右クリック
  • オープンタイプのエクスプローラ
  • クラスを選択
  • 概要を開く
  • メソッドに移動

...そう、ええ、あなたは良いIDEのサポートでそれを行うことができますが、それはまだかなり迷惑です。

3
追加された
ハイホー!やさしい! ;)私の「はるかに難しい」はおそらく誇張されていました。私は単に「より難しい」または「矛盾する」と書くべきです。これを説明するために、Eclipseのクラスメソッドでは、Ctrlキーを押しながらクリックすると、メソッド内でジャンプします(1クリック)。インターフェイスでは、Ctrl +クリック、上に移動、インターフェイス名を右クリック、タイプエクスプローラを開く、クラスを選択、アウトラインを開く、メソッドに移動します。だから、ええ、あなたはそれをIDEのサポートで行うことができますが、それはまだ7クリックかそこら、それはまだかなり迷惑です。
追加された 著者 TLS,
@froodley:私見、体系的にインターフェースを追加することは、単に無駄なノイズを追加することです。それは分離を改善しません、また、それは基礎となる実装が契約を尊重することを確実にしません。それは不必要な間接性、騒音、そして煩わしい開発者を追加するだけです。インターフェースが便利であるケースはたくさんありますが、体系的に適用することはただのバカです。
追加された 著者 TLS,
@froodleyライブラリがインターフェースやクラスを使用しているかどうかに関係なく、私はそれらに縛られています。私は関係ありません。 myLib.doThat(someArg)を呼び出しても、 myLib がインターフェイスであるかクラスであるかは関係ありません。私が本当にそれからいくらか独立しているべきであるならば、私はそれのまわりにラッパーを構築しなければならないでしょう。ただし、ほとんどの場合、このような抽象化を追加することは、有用であるというよりも障害となります。依存関係を入れ替えることはめったにありません。そうすると、ラッパーが他のライブラリにうまく適合しないため、1つではなく2か所で変更されることに気付くでしょう。
追加された 著者 TLS,
@froodley依存関係を置き換える:数年に1回。コードのナビゲート、理解、リファクタリング:毎日。気が狂ったらどこにでもインターフェースを置いてください、私は気にしませんが、長期的にもあなたのものを維持してください。
追加された 著者 TLS,
@Meoここでは Runnable については話していませんが、これは「 Object の特定のサブクラスを見つけたい場合はどうなるでしょう」とよく似た誤った例です。 MyInterface の特定の実装を見つけるのに問題はありません。もちろん、すべてのカスタムクラスに MyInterface を無理なく実装することを決めたのでなければ、さらに大きな問題があります。
追加された 著者 Kayaman,
@Meoルールが「すべてのクラスがインターフェイスを実装する必要がある」という規則で、どのインターフェイスに関する条件がない場合にのみ現実的です。私はプロの環境ではそうは思わないでしょう。私たちが敵対的な環境で作業しているのであれば、インターフェースは何の役にも立たないでしょう。誰かが故意にまたは無意識に誤った実装を書くことができるからです。それは、インターフェースが無用であることを意味するのでしょうか。それらは実装が正しいことを保証しないからです。
追加された 著者 Kayaman,
その価値があるIDEなら、どのように実装にジャンプするかを知っています。貧弱なツールを使用しているのでなければ、これは決して意味がありません。
追加された 著者 Kayaman,
@Meo私はすべてのクラスがインターフェースを実装する必要があると主張することは決してありません。どのような種類のクラスがインタフェースを保証するか(サービスなど)および保証しないもの(エンティティ、値オブジェクトなど)については、ジュニアの開発者には明らかにされるべきです。アーキテクチャーやガイドラインがない場合は、コードベースの形状が悪くなるため、実際には問題ありません。
追加された 著者 Kayaman,
@ Meo私の投稿は私のコメントの後に編集されたと思います。私はすべてのクラスのインターフェースを提唱するわけではありません、そして私はあなたが起こっていることに従うことができないほど悪いアーキテクチャを提唱しません。
追加された 著者 Kayaman,
@ Meoは私の口に言葉を入れずに「間違った」と言う。例えば、単一の実装を持つインターフェースを避ける理由はないと言っています。すべてのクラスがインターフェースを実装しているわけではないと言っています。私はデザインの決定をするときあなたの経験を使う(あるいはもっと経験豊富な人に聞く)と言っています。あなたが話しているコストが開発コストかランタイムコストかはわかりませんが、いずれにしてもごくわずかです。それはインターフェースを避けることによるミクロな最適化のようなものです。
追加された 著者 Kayaman,
それは絶対に重要です。コードをまったく変更せずにmyLibを同じシグネチャを実装するsomeLibに置き換えることができれば、myLibに対して行われた何千ものハード参照を置き換えるのに200万ドルも費やす必要がなくなります。永遠に縛られます。より緩やかな関連付けを実現するために、より高度でより高価でより高価なデカップリング領域がありますが、抽象化だけで処理する場合、デフォルトではソフトウェアは非常に疎結合であり、消費コードを変更せずに置き換えることができます。
追加された 著者 Dave Lau,
難しいですよ。また、パスワードをコードベースにハードコードしたり、ビジネスロジックをモデルに組み込んだりしないでください。それは狭窄です。それは私には「あなたは仕事をしたいのか、したくないのか」ということです。
追加された 著者 Dave Lau,
まったく役に立たないわけではありません。私が具体的にしか扱わないクラスやライブラリを手渡すならば、あなたは私の仕事にあなた自身を密接に結びつけています、そして我々は両方とも箱から出して失敗しました。私の経験では、それはせっかちなジュニア開発者を悩ませますが、ベテランの開発者は契約を結び、それが自殺しないことを自覚したいのです。
追加された 著者 Dave Lau,
@Kayamanそれが編集されたのであれば、そうではなかったでしょう。
追加された 著者 Michael,
@Kayaman私はあなたの最初のコメントを参考にしていました。真実は、「コードをナビゲートすることは、余分なインターフェースのためにますますイライラするようになる」ということです。そしてそれを変えることができるツールはありません。あなたはそれが有効なポイントではないと書いたが、それは間違っている。
追加された 著者 Michael,
@ Kayamanいいえ、あなたが言っているのは、「余分なインターフェース」から実装またはその逆にジャンプすることは無償だということです。違う。
追加された 著者 Michael,
@Kayamanすべてのクラスに独自のインターフェースがある場合、または最も厳密なインターフェースが必要な場合は、IDEで問題なく処理できることに同意します。そして、あなたは最もぴったり合ったインターフェースが何であるか知っていますか?クラス自体過度に使用されているインタフェースからナビゲーションコストがかからないことを期待するのは、単純な方法です。
追加された 著者 Michael,
@Kayamanあなたがすべてを過度に一般化した場合、あなたは必然的に同じ問題に直面するでしょう。インターフェースを持つことが標準的であるならば、誰かが遅かれ早かれ時間を節約してそれらがすべきでないところで既存のものを使うでしょう、そしてIDEは非論理的な実装を提供するでしょう。
追加された 著者 Michael,
@Kayamanもしあなたが貧弱な抽象化を使用しているのでなければ、そのRunnableインターフェースによってその特定の実装を見つけようとしてください。
追加された 著者 Michael,

私はあなたの同僚に同意します。

良い抽象化を作成するのは難しいです。本当に、本当に難しいですね。

抽象化はソフトウェアを複雑にします。彼らはコードとそれについての理由をナビゲートすることを難しくしています。抽象化を超えた変更は複数の場所での変更を必要とすることが多いので、それらは物事を変更することをより困難にします。

クラスが持っているメソッドをコピーしただけのインタフェースは、抽象化が良くありません。あなたが良い抽象化を持っていると言うことができるのは、あなたが複数の異なる実装を想像できる(あるいは実際に持っている)ことができるという時だけです。

抽象化を作成しているときはいつでも、「コードを複雑にしてこれらの部分を切り離すことができるのは本当に価値があるのでしょうか」という質問を自分でする必要があります。

3
追加された
良い抽象化を作成することは、複雑さを取り除くため困難です。悪い抽象化は、代わりにそれを追加します。
追加された 著者 Shizam,
@froodleyあなたのインターフェースとクラスが同じシグネチャを持っているなら、あなたは構築以外の何も切り離していません。
追加された 著者 Frank Hileman,
優れた抽象概念を作成することは困難です。デカップリングの目的に役立つ抽象概念を作成することはそれほど難しくありません。私の消費者が自分のモジュールやクラスを同じシグネチャを提供できる別のモジュールやクラスに置き換えることができれば、私は仕事を正しく終えたと感じますし、彼らは私がしたことと密接に結びついていません。
追加された 著者 Dave Lau,

デカップリングはそれ自体では良いことではありません。それはあなたがそれを必要とするところでは良いことであり、他の至る所では悪いことです。あなたが高い凝集性があるべきである場所でインターフェースを使っているならば、あなたはそれを間違ってやっています。

すべてのインターフェースにはコストと価値があります。それを考慮していないし、盲目的にどこにでも作成しているのであれば、単純に間違っています。

1
追加された
@froodley契約は一連の操作とセマンティクスです。インターフェースは、ユーザーの観点から見れば、クラスとまったく同じように見える一連の操作、つまり一連のシグニチャです。私が言うことができる限り、あなたが「具体的」と呼ぶのはクラスの中のコンストラクタの存在です。分離とは、実装とは無関係にAPIを変更できるということです。クラスがこれを実行でき、インターフェースがこれを実行できますが、実際のデカップリングは複数のインターフェースまたは動的言語を使用することを意味します。
追加された 著者 Frank Hileman,
@froodleyユーザーの観点から見ると、 "concrete"クラスと "interface"と呼ばれるものの唯一の依存関係の違いは、コンストラクターの依存関係です。コンストラクタを提供するクラスを構築することができます。インターフェースのように、コンストラクタを提供しない特別なクラスを構築することはできません。それ以外の点では、インターフェースとクラスはユーザーの観点からは同じです。
追加された 著者 Frank Hileman,
それはあなたの考えです、私のものはまったく反対です。概念的にはモジュール内の高い結束性は、密接に関連している契約を扱うときにも達成されます。契約に基づいた構築は常にあいまいさを排除し、正しい種類の考え方を強制する一方で、後で切り離そうとするのに比べて「安く」非常にスワップ可能なコードベースをもたらすのに比べてコンクリートしかし、繰り返しますが、私はこの主題に関する読み物への言及を探しています。
追加された 著者 Dave Lau,
インターフェースは契約です。クラスはその契約の実装を生成するマシンです。これらは非常に大きく異なります。私はコンクリート機械を扱うことが契約を扱うことと同じであることをまったく確信していません。
追加された 著者 Dave Lau,

データビジネスアプリケーションをプログラムする

現在の接続されているユーザーなどに依存するすべてのビジネスルールのために、オブジェクトが独自の動作を実装するという従来の「真の」OOPには適していません。代わりに私はよく知られている貧血モデル+サービスを持っています、なぜなら私はいくつかの独立した技術的なコンポーネントを除いて私のニーズにもっとふさわしい何かを見つけなかったからです。

私のサービスは常にインターフェースを持っています、なぜなら私が一つの実装を持っていたとしても、私はそれらをモックしたい時があるでしょう。少しだけ要約しますが、それを行う時点で、必要な量や適切な処理方法がわからないので、時間を無駄にしないほうがいいでしょう。 )

もちろん、私はただ1つの実装から始めているので、私のインターフェースは私の実装が公開する必要があるもののほとんどコピーですが、それは意図的です。私が本質的に私のインターフェースをより一般的なものにリファクタリングすることを強制する別の実装を持つ必要があるなら、私はそれが必要とされるときそれをするつもりです。

注:私が使用するサービスのインターフェースには通常の名前を使用します( "I"など何でもありません)。@candied_orangeのように、これらのサービスの消費者は本当にインターフェースであることを気にしないため

0
追加された
Javaでは、もちろん手動でクラスを実装したくないのであれば、(Mockitoなどを使用して)インターフェイスとまったく同じインターフェイスなしでモックすることができます。
追加された 著者 Michael,