2012-06-03 145 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之間沒有耦合。

相關問題