4

数年以来、常識は、実装に対してではなく、インターフェースに対してプログラムする方が良いと指示しているようです。高レベルのコードの場合、これは確かに論理的であるように見えます。たとえば、アプリケーションに複雑なソルバーがある場合は、次のようなものを使用する方がよいようです。

ISolver *solver = solverFactory.getSolver();
solver->solve(inputdata);

それよりも

Solver solver;
solver.solve(inputdata);

最初のコードでは、ソルバーをモックして、単体テストを行うのも簡単です。

しかし、私の質問は、どのレベルでインターフェースを使用するのがもはや意味をなさないかということです。たとえば、アプリケーションにComplexNumberクラス(またはStringクラスなど)がある場合は、次のように記述します。

IComplexNumber *complexNumber = complexNumberFactory.create(1,2);   // 1+2i

書くよりもはるかに複雑なようです(特にパフォーマンスに関して):

ComplexNumber complexNumber(1,2);   // 1+2i

では、インターフェイスの背後に何かを配置する必要があるかどうか、およびインターフェイスの背後に配置するべきでない場合を決定する上で重要な要素はどれですか。

4

3 に答える 3

3

インターフェースに移行する理由は、物事が単純になるか、結合が減る場合です。(それがインターフェースの目的です)。

インターフェースから離れる理由は、それが物事をより複雑にしたり、パフォーマンスを低下させたりする場合です (ただし、それを確実にプロファイリングします)。MockComplexNumber を導入しない限り、IComplexNumber クラスは実際にはクラス階層をより複雑にすると主張しますが、そのようなクラスが役立つとは思えません...そしておそらく物事が遅くなるでしょうが、私はそれを測定します.

しかし、すべてを 1 つの方法で行う必要がある、または決定が固定されているとは思わないでください。インターフェイスを使用して変換するのは非常に簡単です。

于 2010-09-27T10:21:30.320 に答える
1

クラスが果たす役割に応じて、クラスを「サービス」クラスと「価値」クラスに分けると、答えは簡単です。サービス クラスのインターフェイスのみを使用します。あなたの質問では、「ソルバー」はサービスで、「複素数」は値です。

値クラスは new() を使用して簡単に作成できるはずです。これは、コンストラクターで基本型とその他の値クラスのみを受け入れるためです。値クラスは、本物を使用できるため、モックには役立ちません。

サービス クラスをモックすると便利な場合があり、複数の実装が必要になる場合があります。あなたの solverFactory は、naiveSolver、lookupSolver、geneticSolver、mockSolver などを返すことができます。ここでは、インターフェースが役に立ちます。

于 2010-09-28T22:49:56.360 に答える
-2

C++ では、C++ には多重継承があり、インターフェイスは実装を追加できる抽象クラスであるため、問題ではありません。私が最もよく使用されているインターフェイスを見つけたのは、単一の継承を持つ Java と C# であり、クラスにいくつかのものを実装する場合、1 つだけを抽象クラスにすることができ、他はインターフェイスでなければなりません

于 2010-09-27T10:23:10.397 に答える