2012-02-27 10 views
1

Dependency Injectionは、私がオブジェクト指向のコードを書く方法を変えているように感じます。たとえば、以下の私は依存性注入はOOPに逆らっていますか?

Interface: DataAdapter 
SqliteDataAdapter implements DataAdapter 
XMLDataAdapter implements DataAdapter 
OracleDataAdapter implements DataAdapter 

// Initialization 
DataAdapter adapter = new SqliteDataAdapter(); 
DataAdapter adapter = new XMLDataAdapter(); 
DataAdapter adapter = new OracleDataAdapter(); 
DI

せずにどうなるのかですが、私のコードの構造は、DIを使用すると、次のようになります。

Interface: DataAdapter 
SqliteDataAdapter implements ISqliteDataAdapter, DataAdapter 
XMLDataAdapter implements IXMLDataAdapter, DataAdapter 
OracleDataAdapter implements IOracleDataAdapter, DataAdapter 

// Initialization 
ISqliteDataAdapter adapter = new SqliteDataAdapter(); 
IXMLDataAdapter adapter = new XMLDataAdapter(); 
IOracleDataAdapter adapter = new OracleDataAdapter(); 

この変化の理由は、私のモジュールで、私はバインド1インターフェースことができるということです〜1クラス。 これは悪い習慣ですか?はいの場合、正しい解決策は何ですか?

DIはインターフェイスの使用目的をすべて変更しませんか?

EDIT: 次は私のDIコンテナ

bind(ISqliteDataAdapter.class).to(SqliteDataAdapter.class); 
bind(IXMLDataAdapter.class).to(XMLDataAdapter.class); 
bind(IOracleDataAdapter.class).to(OracleDataAdapter.class); 

のために結合された提案として私が行う場合は、どのように私は複数のアダプタを使用することができるだろうか?アプリケーションでXMLDataAdapterとSQLDataAdapterの両方を使用する必要がある場合はどうなりますか?

bind(DataAdapter.class).to(SqliteDataAdapter.class); 

編集:ここでは

は、インスタンスを取得するために、現在の呼び出しです:ここでは

@inject protected ISqliteDataAdapter dataAdapter; 

は、私は1つのだけのインターフェイスを持つとそれを行うべきかです:

@inject protected DataAdapter dataAdapter; 
// In this case I don't have a choice on which type of data adapter It's going to create 
// It's already defined in my module file and it's pointing to one of the 3 DataAdapters 

私が理解しようとしていることは、どのように私のタラを構造化できますか私はDataAdapterのすべてのタイプのためのインターフェイスを持たずに、私はそれが注入しているオブジェクトの種類のコントロールを持っている方法で。

+0

[IoCを使用しているときにインターフェイスの抽象化について混乱しています]の複製が可能です(http://stackoverflow.com/questions/5144622/im-confused-about-interface-abstractions-when-using-ioc) –

+0

そのスレッドを既に読んで、それは私の質問に答えません。 – aryaxt

+3

どうしてですか? 1:1のインターフェースは頭を下げるのに最適な方向ではないことは、かなり明白です。したがって、いいえ、DIはインターフェイスの使用目的全体を変更しません。なぜ2番目の例のようにコードを構造化したいのですか?それぞれの 'adapter'変数を' DataAdapter'と宣言できないのはなぜですか? 3つの新しいインターフェイスが追加する付加価値は何ですか? –

答えて

5

を参照してください。インタフェースを持つ理由は、特定のクラスに依存しないコードを書くことができるようにするためであり、変更を加えずに多数のクラスを扱うということです。私たちが必要とするクラスが1つしかないと予想されても、これは将来変更される可能性があります。インターフェイスをプログラミングすることで、我々が想像することのできない変化についても説明することができます。

DIは、コードのテスト容易性と適応性を最大限にするために、上記の概念を特有の方法で使用しています。だから、私はDIがで、実際にはの良い練習であると言います。

私は、この種のシステムに関係する人には1つの警告が発行されると思います。SqliteDataAdaptorのような本格的なクラスを作成してから、「インターフェイスを抽出する」ボタンを押してISqliteDataAdaptorインターフェイスにする危険性があります。この練習は非常にです。代わりに、ISqliteDataAdaptorが通常は最初に設計され、その後、分かりやすい実装を記述する必要があります。

1

依存性注入とは、インスタンス化されたものを制御し、そのロジックを単一の場所に配置することです。あなたが書いたコードは、あなたが使っている基底型(インターフェース)を変更すべきではありません。

どちらの場合でも、使用するオブジェクトの種類としてDataAdapterが必要です。 従属性注入コンテナではなく、コンテナから取得するインスタンスのタイプを決定します。

も、私はDIがインタフェースを持つことの当然の帰結であると言うでしょうthis

+0

に基づいてインスタンスを取得してください。しかし、あなたは1つのクラスにインターフェイスをバインドすることができますので、この場合の解決方法は何ですか? – aryaxt

+0

しかし、なぜあなたは依存性注入コンテナからインスタンスを取得する場合にDataAdapter型を使用できませんか? @LiviuT。 –

+0

彼のシステムのように、すべてのコンポーネントは潜在的に注射可能であるように設計されています。だから問題は、特に「DIへのプログラミング」、そして特にDIへの厳密な遵守からより多くのものになると思われる。 –