[英]Domain Driven Design - testability and the “new” keyword
我一直在嘗試在我的新項目中遵循域驅動的設計方法。 我一直使用Spring進行依賴注入,這很好地將我的應用程序代碼與構造代碼分開,然而,使用DDD我似乎總是有一個域對象想要創建另一個域對象,這兩個域對象都有狀態和行為。
例如,給定媒體文件,我們希望將其編碼為不同的格式 - 媒體資產調用轉碼服務並接收回調:
class MediaAsset implements TranscodingResultListener {
private NetworkLocation permanentStorage;
private Transcoder transcoder;
public void transcodeTo(Format format){
transcoder.transcode(this,format);
}
public void onSuccessfulTranscode(TranscodeResult result){
Rendition rendition = new Rendition(this, result.getPath(), result.getFormat());
rendition.moveTo(permanentStorage);
}
}
這引發了兩個問題:
有一個工廠來創建這個類是我考慮過的,但是為了包含導致問題的“new”關鍵字,需要大量的代碼開銷。
這里有一種我想念的方法,還是我只是做錯了?
我認為在這種情況下注入RenditionFactory是正確的方法。 我知道它需要額外的工作,但你也從你的班級中刪除了SRP違規。 在業務邏輯中構建對象通常很誘人,但我的經驗是,對象或對象的注入在100次中有99次得到回報。 特別是如果所提到的對象是復雜的,和/或如果它與系統資源交互。
我假設你的單元測試方法是MediaAsset
測試MediaAsset
。 這樣做,我認為工廠是常見的解決方案。
另一種方法是測試整個系統(或幾乎整個系統)。 讓您的測試訪問外部接口[1](用戶界面,Web服務接口等),並為系統訪問的所有外部系統(數據庫,文件系統,外部服務等)創建測試雙精度。 然后讓測試注入這些外部依賴項。
這樣做,您可以讓測試完全與行為有關。 測試與實現細節分離。 例如,您可以使用依賴注入來實現Rendition
:測試不關心。 此外,您可能會發現MediaAsset
和Rendition
不是正確的概念[2],您可能需要將MediaAsset
拆分為兩個,並將其中的一半與Rendition
合並。 同樣,您可以在不擔心測試的情況下完成此操作。
(免責聲明:外層測試並不總是有效。有時你需要測試常見概念,這需要你編寫微測試。然后你可能會再次遇到這個問題。)
[1]最佳級別實際上可能是“域界面”,低於用戶界面的級別,您可以使用域語言而不是字符串和整數,並且您可以在這里談論域操作而不是按鈕點擊和焦點事件。
[2]也許這實際上是你的問題: MediaAsset
和Rendition
是正確的概念嗎? 如果你問你的域專家,他知道這些是什么嗎? 如果沒有,你真的在做DDD嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.