是的,這是一個良好的開端,但是,其接口比有依賴注入少一個優先的。如果你所有的遺留類都獲得了接口,但是在內部隱藏,它們仍然是相互依賴的,這些類仍然不容易測試。舉例來說,假設你有一個看起來像這樣兩類:
Public Class LegacyDataAccess
Public Function GetAllSales() As List(Of SaleDto)
' Do work with takes a long time to run against real DB
End Function
End Class
Public Class LegacyBusiness
Public Function GetTotalSales() As Integer
Dim dataAccess As New LegacyDataAccess()
Dim sales As List(Of SaleDto) = dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
我知道你已經說... 「我希望遺留代碼至少是分層的那麼好」,但讓用它作爲一些遺傳代碼的例子,這些遺傳代碼很難測試。難以測試的原因是因爲代碼伸出數據庫並對數據庫執行耗時的查詢,然後從中計算結果。因此,爲了以當前狀態測試它,您需要先將大量測試數據寫入數據庫,然後運行代碼以查看它是否基於插入的數據返回正確的結果。不得不寫一個這樣的測試是有問題的,因爲:
- 這是一個痛苦的代碼寫入到安裝測試
- 測試將是脆弱,因爲它取決於正常工作外數據庫和它含所有正確的支持數據
- 測試將需要很長時間才能運行
正如你正確地觀察,接口單元測試非常重要。因此,當你建議,讓我們來添加界面,看看它使任何更容易測試:
Public Interface ILegacyDataAccess
Function GetAllSales() As List(Of SaleDto)
End Interface
Public Interface ILegacyBusiness
Function GetTotalSales() As Integer
End Interface
Public Class LegacyDataAccess
Implements ILegacyDataAccess
Public Function GetAllSales() As List(Of SaleDto) _
Implements ILegacyDataAccess.GetAllSales
' Do work with takes a long time to run against real DB
End Function
End Class
Public Class LegacyBusiness
Implements ILegacyBusiness
Public Function GetTotalSales() As Integer _
Implements ILegacyBusiness.GetTotalSales
Dim dataAccess As New LegacyDataAccess()
Dim sales As List(Of SaleDto) = dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
所以現在我們有接口,但實際上,如何使它變得更容易測試?現在我們可以輕鬆創建一個模擬數據訪問對象,它實現相同的接口,但這不是真正的核心問題。問題是,我們如何讓業務對象使用模擬數據訪問對象而不是真實的?要做到這一點,你需要通過引入依賴注入來將你的重構提升到下一個層次。真正的罪魁禍首是New
關鍵字在以下行業務類:
Dim dataAccess As New LegacyDataAccess()
商務艙清楚地依賴於數據訪問類,但目前它是隱藏這一事實。這是說謊的依賴關係。這就是說,來吧,很簡單,只需調用這個方法,我就會返回結果 - 這就是所需要的。當真的時,它需要更多的東西。現在,讓我們說,我們從臥談它的依賴停止了它,並使它所以它毫不掩飾地說他們,是這樣的:
Public Class LegacyBusiness
Implements ILegacyBusiness
Public Sub New(dataAccess As ILegacyDataAccess)
_dataAccess = dataAccess
End Sub
Private _dataAccess As ILegacyDataAccess
Public Function GetTotalSales() As Integer _
Implements ILegacyBusiness.GetTotalSales
Dim sales As List(Of SaleDto) = _dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
現在,你可以看到,這個類是多容易測試。我們不僅可以輕鬆創建模擬數據訪問對象,現在我們可以輕鬆地將模擬數據訪問對象注入到業務對象中。現在我們可以創建一個模擬,它可以快速而輕鬆地返回我們希望返回的數據,然後查看業務類是否返回正確的計算 - 不涉及數據庫。
不幸的是,雖然向現有類添加接口非常簡單,但重構它們以使用依賴注入通常需要更多的工作。您可能需要計劃出哪些類最適合首先處理。您可能需要創建一些中介的舊式封裝,這些封裝符合代碼的習慣,因此您在重構代碼的過程中不會破壞現有代碼。這並不是一件快速簡單的事情,但如果你耐心並且長期堅持下去,就有可能做到這一點,你會很高興你做到了。
感謝DI提醒。 +1。 – w0051977
並提供全面的解答。 – w0051977
謝謝。我將不勝感激,如果你會看看我的數據倉庫/ VB.NET問題在這裏:http://stackoverflow.com/questions/18495622/data-warehouse-type-solution#18495622。你提供了設計模式類型問題的好答案,所以我想我會問。 – w0051977