8

SOLID の原則によれば、クラスは他のクラスに依存することはできず、依存関係を注入する必要があります。それは簡単です:

class Foo
{
    public Foo(IBar bar)
    {
        this.bar = bar;
    }

    private IBar bar;
}

interface IBar 
{
}

class Bar: IBar 
{
}

しかし、IBar の背後にある正確な実装を知らずに、Foo クラスで Bar を作成できるようにしたい場合はどうすればよいでしょうか? ここで 4 つの解決策を考えることができますが、それらにはすべて欠点があるようです。

  1. オブジェクトのタイプを注入し、リフレクションを使用する
  2. ジェネリックの使用
  3. 「Service Locator」を使用して Resolve() メソッドを呼び出します。
  4. 分離されたファクトリ クラスを作成し、それを Foo に挿入します。

class Foo
{
    public void DoSmth(IBarCreator barCreator) 
    {
        var newBar = barCreator.CreateBar();
    }
}

interface IBarCreator 
{
    IBar CreateBar();
}

class BarCreator : IBarCreator
{
    public IBar CreateBar()
    {
        return new Bar();
    }
}

最後のケースは当然のようですが、BarCreator クラスのコードが少なすぎます。では、どちらが良いと思いますか?

4

5 に答える 5

3

これが工場が作られたものです。

ファクトリのコードが少なすぎると感じた場合は、インスタンスをインラインで作成するだけでどのような利点があるかを自問してください。利点が追加されたコードのコストを上回る場合は、心配する必要はありません。

私は個人的にサービスの場所を避けるか、本当に使用する必要がある場合は、とにかく工場の後ろに隠します. サービスの場所は簡単に悪用される傾向があり、コンテナーが関係のないコードに侵入する可能性があります。

便宜上、一部のコンテナでは、コンテナがコンポーネントのインスタンスを作成するときに使用するファクトリを指定できます。この場合、クラスは直接依存する可能性がありIBarますが、コンテナーはIBarCreator新しいインスタンスが必要なときに呼び出します。たとえば、Castle Windsorの API にはUseFactoryとがあります。UseFactoryMethod

于 2011-08-26T11:42:04.420 に答える
3

Func<IBar>この場合、 a を「注入」するのが好きです。そのようです:

class Foo
{
    public Foo(Func<IBar> barCreator)
    {
        this.bar = barCreator();
    }

    private IBar bar;
}

interface IBar 
{
}
于 2011-08-26T11:35:10.450 に答える
2

冗長ファクトリインターフェイスに問題がある場合は、ここで2つのアプローチをとることができます。

ジェネリックで再利用可能にする:

interface IFactory<T>
{
 T Create();
}

class DefaultConstructorFactory<T> : IFactory<T>, where T: new()
{
 public T Create() { return new T();}
}

または、匿名関数をファクトリとして使用します。

public void DoSomething(Func<IBar> barCreator)
{
 var newBar = barCreator();
 //...
}
于 2011-08-26T11:37:33.393 に答える
2

それはすべて、正確なシナリオとニーズによって異なります。
あなたが言及したように、最もよく使用されるアプローチはfactoryだと思います。
IoC フレームワーク (Ninject、Sprint.Net、Castle Windsor など。こちらを参照) を使用している場合は、サービス ロケーターも実行可能なソリューションです。

于 2011-08-26T11:33:50.077 に答える
0

「Foo クラスで Bar を作成できるようにしたい」と言うと、「関心の分離」というもう 1 つのルールが適用されるように感じます。したがって、クラス作成のタスクを別のものに委任する必要があり、Foo はそのタスクについて心配する必要はありません。

于 2011-08-26T11:33:42.143 に答える