2012-06-03 135 views
3

我一直在试图理解依赖注入和我一直在取得进展,但我想知道这些代码的好处/差异/重要性。我想知道这些代码的好处/不同/重要性。他们看起来是一样的,但不同的方法依赖注入 - 这两个代码之间有什么区别?

//dependency injection - (as was claimed) 
Customer customer = new Customer(10); 

IOrderDAO orderDAO = new OrderDAO(); 
customer.setOrderDAO(orderDAO); 
customer.getOrdersByDate(); 

OR

//Unknown Pattern - Please what pattern is this? 
Customer customer = new Customer(10); 
IOrderDAO orderDAO = new OrderDAO(); 
orderDAO.getOrderByDate(customer.id); 

这有什么错第二种方法?

谢谢。

+1

它没有什么不对。 – bmargulies

+0

我认为这是有区别的 - 见下文。 – duffymo

+0

我没有说没有区别。 – bmargulies

回答

3

两者都不像依赖注入给我;不应该打电话给new

依赖注入是由一个与所有依赖连接的bean工厂完成的。它实例化bean并给它们依赖。

我根本没有看到豆厂。依赖注入是一个很长的路要走。

客户在第一个示例中使用setter获取OrderDAO。第一个说客户必须在其API中公开持久性方法。它负责保存订单。我想说这是一个可怜的问题分离,因为现在客户必须了解订单。

第二个让客户与OrderDAO分开。您将客户ID传递给OrderDAO,并以该客户的名义保存订单。我认为这是一个更好的问题分离。

但是没有一个是依赖注入的好例子。

DI的第一个也是最好的描述来自Martin Fowler。我建议你这仔细阅读:

http://martinfowler.com/articles/injection.html

这是八岁,但还是即期。

+0

依赖注入不需要容器 - 它仅仅意味着类不负责创建或定位它们的依赖关系 – Lee

+0

不需要,但我能想到的每个示例都有一个:PicoContainer,Spring,Guice。此外,我的观点与DI没有多大关系,一切与分离关注有关。 – duffymo

+0

请你可以显示一些代码。只需简单地勾画一下我就会从中选择。直到昨天,依赖注入一直是一个谜,我有一个更好的理解,你可以看到我仍然困惑 – codingbiz

3

它们都不是正确的依赖注入示例。这些都是数据访问模式的例子。第一个例子是active record pattern。将orderDAO设置为客户实体的依赖关系,我们可以调用属性或setter注入。

第二个例子可能是repository pattern.这里的依赖关系模式是方法注入,它转化为具有一些参数的常见调用方法(这里的参数是方法的依赖关系)。

开始学习DI模式的好方法是读取this book。也有许多网上资源,像那些视频:

我也建议在谷歌(it's not the same as dependency injecion)寻找依赖倒置原则。

1

这是一个奇怪的例子,但第一个演示什么是依赖注入容器会做和第二个演示一个对象传递一个参数到另一个对象。第一个嵌入它的依赖作为调用类的实例变量;第二个更具程序性。 本身也不是。这取决于你的依赖有多复杂,以及你想如何管理代码。

只看你提供的注射器代码,为什么你想要使用依赖注入并不明显。但暂时考虑一个更复杂(更典型)的例子。

的CustomerService:

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的实现。这意味着,例如,您可以非常容易地通过使用StubOrderDAO(始终返回硬编码的客户)初始化它来为CustomerService引导单元测试。同样,您的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中执行的任何聚合或业务逻辑处理(此处未显示简洁)。

这是否更有意义?

+0

好了。但不应该__service.setDao(service)__ be ** service.setDao(dao)** – codingbiz

+0

好的。我会解决它。 –

1

不要混淆控制倒置和依赖注入(如另一个答案)。我描述了依赖注入和IOC在这里:http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci

//dependency injection - (as was claimed) 
Customer customer = new Customer(10); 

IOrderDAO orderDAO = new OrderDAO(); 
customer.setOrderDAO(orderDAO); 
customer.getOrdersByDate(); 

不,我不认为这是DI。我会尽可能地把它写成糟糕的代码。客户不应该注意到它所强制的持久层。它打破了单一责任原则,因为客户还必须处理订单。

//Unknown Pattern - Please what pattern is this? 
Customer customer = new Customer(10); 
IOrderDAO orderDAO = new OrderDAO(); 
orderDAO.getOrderByDate(customer.id); 

它不是特定的模式,但更好的代码,因为在customerorderDao之间没有耦合。

相关问题