これは奇妙な例ですが、最初の例は依存性注入コンテナーが行うことを示し、2 番目の例は1 つのオブジェクトが別のオブジェクトに引数を渡すことを示しています。1 つ目は、その依存関係を呼び出し元クラスのインスタンス変数として埋め込みます。2 つ目は、本質的に手続き型です。それ自体はどちらも間違っていません。依存関係の複雑さとコードの管理方法によって異なります。
あなたが提供したインジェクター コードを見るだけでは、依存性注入を使用したい理由はすぐにはわかりません。しかし、もう少し複雑な (そしてより典型的な) 例を考えてみましょう。
顧客サービス:
public class CustomerService implements ICustomerService {
private IOrderDAO orderDao;
public void setOrderDAO(IOrderDAO orderDao) {
this.orderDao = orderDao;
}
public Order getOrderByDate(Integer customerId, Date date) {
return this.orderDao.findOrderByDate(customerId, date);
}
}
OrderDAO (デフォルトの実装):
public OrderDAO implements IOrderDAO {
private javax.sql.DataSource dataSource;
public void setDataSource(javax.sql.DataSource dataSource) {
this.dataSource = dataSource;
}
public Order findOrderByDate(Integer customerId, Date date) {
...
}
}
StubOrderDAO (スタブ実装):
public StubOrderDAO implements IOrderDAO {
public Order findOrderByDate(Integer customerId, Date date) {
return new HardCodedOrder(); // this class would extend or implement Order
}
}
実行時に、 のインスタンスは、CustomerService
どの IOrderDAO の実装が使用されているかわかりません。これは、たとえば、CustomerService の単体テストを初期化することで非常に簡単にブートストラップできることを意味しますStubOrderDAO
(常にハードコードされた顧客を返します)。同様に、DataSource の実装も異なる場合があります (モック データ ソースか、異なるランタイム環境で異なるデータ ソースのいずれか)。
したがって、本番用のインジェクターは次のようになります。
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new OrderDAO();
javax.sql.dataSource dataSource = jndiContext.lookup("java:comp/env/MyDataSource");
// initialize
dao.setDataSource(dataSource);
service.setOrderDAO(dao);
return service;
一方、ローカル (テスト) データ ソースを使用するためのインジェクターは次のようになります。
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new OrderDAO();
javax.sql.dataSource dataSource = new DriverManagerDataSource("jdbc:sqlserver:yadayada...", "myUsername", "myPassword");
// initialize
dao.setDataSource(dataSource);
service.setOrderDAO(dao);
return service;
統合テスト用のインジェクターは次のようになります。
// instantiate
CustomerService service = new CustomerService();
OrderDAO dao = new StubOrderDAO();
// initialize
service.setOrderDAO(dao);
return service;
したがって、これは基本的に、適切な階層化と関心の分離を実装する方法です。つまり、データベースにアクセスする方法は、ドメイン モデルを作成するためにデータにアクセスする方法とは無関係であり、どちらも、実行する集計またはビジネス ロジック処理とは無関係です。でCustomerService
(簡潔にするためにここには示していません)。
それはもっと理にかなっていますか?