2009-10-02 71 views
2

或者,基本實體驗證是否考慮了一個或多個規範?BDD/DDD在哪裏放置基本實體驗證規範?

一般來說,在實際的實體中,還是在規範之外,保持基本的實體驗證(名稱不能爲空或空,日期必須大於xxx)會更好嗎?

如果在規範中,那會是什麼樣子?你會爲每個字段提供一個規範,還是將其全部包裝在一個EntityIsValid類型規範中?

回答

2

在我看來,一旦人們對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類現在不可能進入該規則被破壞的狀態。

如果稍後發現規則更復雜,或者在許多不同概念之間共享,則始終可以將其提取到規範中。

+0

如果規則稍微複雜一些,如: ... 字符串名稱; //不得在數據庫中複製 ... – Burt 2010-01-09 01:19:13

+2

由於併發性問題,唯一性約束實際上只能在數據庫本身中處理。即使您要預先檢查唯一性,另一個併發寫入可能會在您執行之前插入完全相同的值。這意味着您不能將唯一性編碼爲不變量,但您仍然可以通過執行前期檢查來幫助用戶。但是,這對我來說不是驗證,而是對可用性的改進。 – 2010-01-09 08:41:05

1

實體具有數據和行爲,所以讓你的實體確保他們的不變式是邁向恕我直言的方式。否則,你可能會以anemic domain model [福勒]結束。

如果您的上下文允許您按照Mark Seemann的建議強制執行規則,那麼您的模型中沒有所有「IsValid」和/或「BrokenRules」邏輯會很好。

我一直在兩種環境,我們發現自己需要上述方案,但:

  1. 一個經典的響應/請求的Web解決方案,其中網頁顯示全部破碎在無法保存的實體規則。

  2. 該模型是從外部更新的數據庫中讀取的(因此,即使設置邏輯,實體無效也是不可能的,除非讓ORM使用setter,但對於我們來說整點了解有效性)。

相關問題