7

私はこれらの3つの用語にしばしば混乱します。これらの3つは私に似ています。誰かが例を挙げて、それらを明確に説明してくれませんか。

私は同様の投稿を見たことがあり、完全には理解していません。

4

3 に答える 3

20

依存性注入とは、クラスがすべての依存関係を見つける場所を知る必要があるのではなく、その依存関係が何であるかをクラスに伝えるパターンを指します。

したがって、たとえば、次のようになります。

public class UserFetcher {
   private final DbConnection conn = 
      new DbConnection("10.167.1.25", "username", "password");

   public List<User> getUsers() {
      return conn.fetch(...);
   }
}

このようなものに:

public class UserFetcher {
   private final DbConnection conn;

   public UserFetcher(DbConnection conn) { 
      this.conn = conn;
   }

   public List<User> getUsers() {
      return conn.fetch(...);
   }
}

これにより、コード内のカップリングが減少します。これは、単体テストを行う場合に特に役立ちますUserFetcherUserFetcher これで、 にあるデータベースに対して常に実行する代わりに、テスト データベースに を10.167.1.25渡すことができます。DbConnectionまたは、高速なテストでさらに役立つのはDbConnection、データベースに接続することさえせず、リクエストを破棄するだけの実装またはサブクラスを渡すことです!

ただし、この種のプリミティブな依存関係の注入では、オブジェクト グラフ全体を通じて依存関係を渡すことで、グローバル変数 (またはローカルにインスタンス化されたオブジェクト) を使用して依存関係にアクセスすることを置き換えたため、ワイヤリング(オブジェクトにその依存関係を提供すること) がより困難になります。 .

が の依存関係であり、UserFetcherが の依存関係である場合を考えてみてください。次に、インスタンスをに渡す必要があり、直接使用する必要がない場合でも、インスタンスを...に渡す必要があります。AccountManagerAdminConsoleAdminConsoleDbConnectionAccountManagerAccountManagerUserFetcherAdminConsoleAccountManagerDbConnection

制御コンテナー (Spring、Guice など)の反転は、依存関係を自動的に配線 (提供) することにより、依存関係の注入を容易にすることを目的としています。これを行うには、IoC コンテナーにオブジェクト (Spring ではこれをbeanと呼びます) を提供する方法を一度伝えます。別のオブジェクトがその依存関係を要求するたびに、コンテナーによって提供されます。

コンストラクター注入を使用した場合、最後の例は Guice で次のようになります。

public class UserFetcher {
   private final DbConnection conn;

   @Inject //or @Autowired for Spring
   public UserFetcher(DbConnection conn) { 
      this.conn = conn;
   }

   public List<User> getUsers() {
      return conn.fetch(...);
   }
}

そして、IoC コンテナーを構成する必要があります。Guice では、これはModule;の実装によって行われます。Springでは、多くの場合 XML を介してアプリケーション コンテキストを構成します。

public class MyGuiceModule extends AbstractModule {    
    @Override
    public void configure() {
       bind(DbConnection.class).toInstance(
           new DbConnection("localhost", "username", "password"));
    }
}

UserFetcherが Guice または Spring によって構築されると、DbConnectionが自動的に提供されるようになりました。

Guice には、依存性注入の背後にある動機と、さらに IoC コンテナーの使用に関する非常に優れた Wiki 記事があります。隅々まで読む価値があります。

戦略パターンは、オブジェクトの代わりにロジックを注入する依存性注入の特殊なケースです( Java では、ロジックはオブジェクトにカプセル化されます)。これは、独立したビジネス ロジックを分離する方法です。

たとえば、次のようなコードがあるとします。

public Currency computeTotal(List<Product> products) {
   Currency beforeTax = computeBeforeTax(products);
   Currency afterTax = beforeTax.times(1.10);
}

しかし、このコードを新しい管轄区域に拡張し、別の売上税スキームを適用したい場合はどうすればよいでしょうか? 次のように、税金を計算するロジックを挿入できます。

public interface TaxScheme {
    public Currency applyTax(Currency beforeTax);
}

public class TenPercentTax implements TaxScheme {
    public Currency applyTax(Currency beforeTax) {
        return beforeTax.times(1.10);
    }
} 

public Currency computeTotal(List<Product> products, TaxScheme taxScheme) {
    Currency beforeTax = computeBeforeTax(products);
    Currency afterTax = taxScheme.applyTax(beforeTax);
    return afterTax;
}
于 2012-09-22T06:36:00.673 に答える
2

制御の反転は、ランタイム フレームワークがすべてのコンポーネント (Spring など) を結び付けることを意味します。依存性注入は IoC の一種です (別の形式の IoC が存在するかどうかはわかりません) ( http://en.wikipedia.org/wiki/Inversion_of_controlを参照)。

戦略パターンは、アルゴリズムを別のものに置き換えることができる設計パターン (GoF によって定義された) です (参照: http://en.wikipedia.org/wiki/Strategy_pattern )。これは、同じインターフェースのいくつかの実装を提供することによってアーカイブされます。Spring のような IoC を使用する場合、インターフェースの実装が複数あり、構成によって実装を別の実装に切り替えることができる場合は、戦略パターンを使用しています。

于 2012-09-22T08:05:00.020 に答える
0

また、この問題に焦点を当てた Spring のドキュメントの導入の章を読むことをお勧めします: Spring Framework
の紹介 最初の数段落で十分です。

また、これは次のリンクにもリンクしています: Inversion of Control Containers and the Dependency Injection pattern
これらの非常に重要なコア概念の動機付けビューも提供します。

于 2012-09-26T10:38:34.337 に答える