1

依存性注入について知って以来、何かを注入するか、クラス内に作成するかを決定するのに苦労しています。

DI を使用しない次のサンプルを検討してください。

class Car
{
    private Wheels _wheels;
    private Chasis _chasis;
    private Fuel _fuel;

    public Car()
    {
        _wheels = new Wheels();
        _chasis = new Chasis();
        _fuel = new Fuel();
    }

    public ExhaustGas Exhaust
    {
        get
        {
            return new ExhaustGas();
        }
    }
}

車内で作成されたこれらのインスタンスのうち、何を注入しますか? もしそうなら、あなたはどのように決定しますか?

これが私の推論です:

  • 燃料- 燃料は外部ソースから取得され、燃料が変化する理由が明確にわかるため、それに抽象化 (IFuel) を追加して注入します。
  • 車輪- 車輪は車の一部ですが、簡単に交換できます。だから私はそれも注射するべきだと言います。
  • シャーシ- これはもっと考えなければなりません。シャーシは車の非常に重要な部分であるため、外部依存として取得するのは少し奇妙に思えます. ただし、シャーシだけでテストを実行することはできますし、ダミーを使用して車をテストすることもできます (そうすべきかどうかはわかりませんが)。オブジェクトのそのような重要な部分を注入する必要がありますか?
  • ExhaustGas - これはさらに難しい。IExhaustGas をオンデマンドで作成するファクトリを注入することはできますが、そうすべきかどうかはわかりません。このインスタンスはオンデマンドで作成されるため、ファクトリとして注入するべきではありませんか? そうでない場合、この場合の私の推論は何ですか?

ここで提示した変数についての意見と、いつ何かを注入するか、いつ注入しないかを決定する方法に関するより一般的な理由をお聞かせください。

4

1 に答える 1

2

経験則として、すべての外部依存関係を注入する必要があります。理由は簡単です。テスト用に依存関係をモック化し、必要に応じて後で置き換える柔軟性を持たせたいからです。

すべてを注入する複雑さに対処するには、いくつかの戦略があります。いくつかのものだけを注入したい場合は、オプションにします。

class Foo {

    private _bar
    private _baz

    public Foo(Bar bar = null, Baz baz = null) {
        if (!bar)  bar = new Bar;
        if (!baz)  baz = new Baz;

        _bar = bar
        _baz = baz
    }

}

これには、必要なインスタンス化の狂気を回避しながら、依存性注入のすべての利点があります。

CarDependencyFactoryまたは、必要なすべての依存関係を 1 つのクラスでインスタンス化できるなどのファクトリを使用します。必要に応じて、それもオプションにします。

依存性注入コンテナー/マネージャー/フレームワークも役立ちます。肝心なのは、依存関係を置き換える必要がなく、あるコードを別のコードに結合しても問題ないことが本当に確実でない限り、すべてを注入する必要があるということです。

How Not Kill Your Testability Using Staticsも参照してください。

于 2012-11-21T16:49:09.867 に答える