或者,基本實體驗證是否考慮了一個或多個規範?BDD/DDD在哪裏放置基本實體驗證規範?
一般來說,在實際的實體中,還是在規範之外,保持基本的實體驗證(名稱不能爲空或空,日期必須大於xxx)會更好嗎?
如果在規範中,那會是什麼樣子?你會爲每個字段提供一個規範,還是將其全部包裝在一個EntityIsValid類型規範中?
或者,基本實體驗證是否考慮了一個或多個規範?BDD/DDD在哪裏放置基本實體驗證規範?
一般來說,在實際的實體中,還是在規範之外,保持基本的實體驗證(名稱不能爲空或空,日期必須大於xxx)會更好嗎?
如果在規範中,那會是什麼樣子?你會爲每個字段提供一個規範,還是將其全部包裝在一個EntityIsValid類型規範中?
在我看來,一旦人們對DDD有所瞭解,他們就會選擇規範模式,並將它應用到任何地方。那確實是反模式的。
我看到規範模式的地方以及我理解Domain-Driven Design的方式是,它是一種設計模式,您可以選擇在需要改變獨立於實體的業務規則時應用的設計模式。
請記住,DDD是一種迭代的方法,所以你不必在第一次拿到它的時候「正確」。我將開始在實體內部進行基本驗證。這符合關於OOD的基本思想,因爲它可以讓表示概念的對象瞭解數據的有效範圍。
在大多數情況下,您甚至不需要顯式驗證,因爲應該設計實體以使約束表示爲不變量,從而無法創建違反約束的實例。
如果你有一個規則,即名稱不能爲空或空的,你可以積極地執行它直接在你的實體:
public class MyEntity
{
private string name;
public MyEntity(string name)
{
if(string.IsNullOrEmpty(name))
{
throw new ArgumentException();
}
this.name = name;
}
public string Name
{
get { return this.name; }
set
{
if(string.IsNullOrEmpty(value))
{
throw new ArgumentException();
}
this.name = value;
}
}
}
該名稱不能爲空的規則現在是類不變:MyEntity類現在不可能進入該規則被破壞的狀態。
如果稍後發現規則更復雜,或者在許多不同概念之間共享,則始終可以將其提取到規範中。
實體具有數據和行爲,所以讓你的實體確保他們的不變式是邁向恕我直言的方式。否則,你可能會以anemic domain model [福勒]結束。
如果您的上下文允許您按照Mark Seemann的建議強制執行規則,那麼您的模型中沒有所有「IsValid」和/或「BrokenRules」邏輯會很好。
我一直在兩種環境,我們發現自己需要上述方案,但:
一個經典的響應/請求的Web解決方案,其中網頁顯示全部破碎在無法保存的實體規則。
該模型是從外部更新的數據庫中讀取的(因此,即使設置邏輯,實體無效也是不可能的,除非讓ORM使用setter,但對於我們來說整點了解有效性)。
如果規則稍微複雜一些,如: ... 字符串名稱; //不得在數據庫中複製 ... – Burt 2010-01-09 01:19:13
由於併發性問題,唯一性約束實際上只能在數據庫本身中處理。即使您要預先檢查唯一性,另一個併發寫入可能會在您執行之前插入完全相同的值。這意味着您不能將唯一性編碼爲不變量,但您仍然可以通過執行前期檢查來幫助用戶。但是,這對我來說不是驗證,而是對可用性的改進。 – 2010-01-09 08:41:05