31

ユニットテストで足を濡らそうとしています。別の実装に交換する必要がある何らかの理由が予測されない限り、私は現在、クラスのインターフェイスを作成する習慣がありません。さて、今私は理由を予見します:あざける。

ほんの一握りのインターフェースからおそらく数百のインターフェースに移行することを考えると、最初に頭に浮かんだのは、これらすべてのインターフェースをどこに置くべきかということでした。それらをすべての具体的な実装と混ぜ合わせるだけですか、それともサブフォルダーに入れる必要がありますか。たとえば、コントローラーインターフェイスはroot / Controllers / Interfaces、root / Controllers、または他の何かに完全に配置する必要がありますか?何をアドバイスしますか?

4

5 に答える 5

24

組織について説明する前に:

さて、今私は理由を予見しています: 嘲笑.

クラスでモックすることもできます。サブクラス化は、常にインターフェイスを作成するのではなく、オプションとしてモッキングに適しています。

インターフェイスは信じられないほど便利ですが、インターフェイスを作成する理由がある場合にのみインターフェイスを作成することをお勧めします。クラスが正常に機能し、ロジックの観点からより適切な場合に作成されるインターフェイスをよく見かけます。実装をモックアウトできるようにするためだけに、「何百ものインターフェイス」を作成する必要はありません。カプセル化とサブクラス化は、そのために非常にうまく機能します。

そうは言っても、関連する型を同じ名前空間にグループ化することが最も理にかなっている傾向があるため、通常はクラスとともにインターフェイスを整理します。主な例外は、インターフェイスの内部実装です。これらはどこでもかまいませんが、「プライベート」インターフェイス実装 (および純粋に内部実装である他のクラス) に特に使用する「内部」フォルダー + 内部名前空間を作成することがあります。 )。これにより、メインの名前空間を整然とした状態に保つことができるため、型は API 自体に関連するメインの型だけになります。

于 2011-06-16T00:45:21.053 に答える
15

ほとんどすべてのインターフェイスが 1 つのクラスのみをサポートする場合は、同じ名前空間の下にあるクラス自体と同じファイルにインターフェイスを追加することをお勧めします。そうすれば、プロジェクトを実際に混乱させたり、インターフェイス専用のサブフォルダーを必要としたりする可能性のある、インターフェイス用の別のファイルがありません。

同じインターフェイスを使用して別のクラスを作成していることに気付いた場合は、完全に手に負えない場合を除き、クラスと同じフォルダーにインターフェイスを分割します。しかし、同じフォルダーに何百ものクラスファイルがあるとは思えないので、そうなるとは思いません。その場合は、機能に応じてクリーンアップしてサブフォルダーを作成する必要があり、残りは自動的に処理されます。

于 2011-06-16T01:19:23.460 に答える
1

依存関係を分離するためにプロジェクトに何百ものインターフェイスが必要な場合、設計に問題がある可能性があることに気付きました。これは、これらのインターフェイスの多くが最終的に 1 つのメソッドしか持たない場合に特に当てはまります。これに代わる方法は、オブジェクトでイベントを発生させ、依存関係をそれらのイベントにバインドすることです。例として、データの永続化をモックアウトしたいとしましょう。これを行う完全に合理的な方法の 1 つは、次のようにすることです。

public interface IDataPersistor
{
    void PersistData(Data data);
}

public class Foo
{
    private IDataPersistor Persistor { get; set; }
    public Foo(IDataPersistor persistor)
    {
        Persistor = persistor;
    }

    // somewhere in the implementation we call Persistor.PersistData(data);

}

インターフェイスやモックを使用せずにこれを行う別の方法は、次のようにすることです。

public class Foo
{
    public event EventHandler<PersistDataEventArgs> OnPersistData;

    // somewhere in the implementation we call OnPersistData(this, new PersistDataEventArgs(data))
}

次に、私たちのテストでは、モックを作成する代わりにこれを行うことができます:

Foo foo = new Foo();
foo.OnPersistData += (sender, e) => { // do what your mock would do here };

// finish your test

これは、モックを過度に使用するよりもクリーンであることがわかりました。

于 2011-06-16T04:18:39.537 に答える
1

場合によります。私はこれを行います: 依存するサード パーティ アセンブリを追加する必要がある場合は、具体的なバージョンを別のクラス ライブラリに移動します。そうでない場合は、同じディレクトリと名前空間に並んでいる可能性があります。

于 2011-06-16T00:46:31.413 に答える