我應該在哪裏將域對象的驗證邏輯放在我的解決方案中?我應該把它們放在域類,業務層還是其他?你在哪裏把驗證放在有域驅動設計的項目中?
我也想利用來自Microsoft企業庫的驗證應用程序塊和策略注入應用程序塊來做到這一點。
我應該用什麼驗證策略來很好地融合所有這些?
非常感謝!
我應該在哪裏將域對象的驗證邏輯放在我的解決方案中?我應該把它們放在域類,業務層還是其他?你在哪裏把驗證放在有域驅動設計的項目中?
我也想利用來自Microsoft企業庫的驗證應用程序塊和策略注入應用程序塊來做到這一點。
我應該用什麼驗證策略來很好地融合所有這些?
非常感謝!
這取決於。首先 - 您需要了解您正在驗證的內容。
您可以驗證:
正如你所看到的 - 這些驗證在性質上是不同的,所以他們should be separated。它們的重要性varies too(請參閱「所有規則都不相等」段落)。
事情,你可能要考慮的是not allowing域對象是處於無效狀態。
這將大大降低複雜性,因爲在當前時間範圍內,您知道該對象是有效的,並且您只需要驗證當前任務相關的事情以便進步。
另外,您應該考慮避免使用您的域模型中的工具,因爲它應該儘可能免費提供基礎設施。
另一件事 - 包容使用價值對象。這對驗證封裝非常有用。
我通常把它放在域對象中。這是因爲域對象是我關心驗證的事情,所以如果特定對象的規則發生變化,我知道在哪裏更新它,而不必在某些特定的驗證類/文件中搜索大量不相關的實體規則。
我意識到這可能不被認爲是POCO,但每個項目都有特定的例外,這對我來說通常是有意義的。同樣,在某些項目中,從視圖中引用域實體是有意義的,因此實現IPropertyChanged而不是不斷地將實體中的值複製到整個其他視圖特定對象集。
我做了驗證的老方法是我有一個像下面這樣的IValidator接口,每個實體都實現了。
public interface IValidator
{
IList<RuleViolation> GetViolations();
}
現在我做到這一點使用NHibernate的驗證(不需要使用NHibernate的ORM趁驗證庫的它是通過屬性簡單地完成
//I can't remember the exact syntax but it is very similar to this
public class MyEntity
{
[NHibernateValidation(Length(min=1, max=10)]
public String Name {get;set;}
}
//... and then later ...
NHibernateValidator.Validate(myEntity);
編輯:我打消了我因爲克里斯告訴我它現在和NHibernate Validation
以前一般不會是企業圖書館的巨大粉絲,所以你可以根據自己的需要做任何一項。
將它放在域類中可以確保驗證總是完成,但可能會導致類臃腫。它也可能違背單一責任原則,取決於你如何解釋(它增加了驗證的責任)。將它放在域類中也會將您限制爲一種驗證。另外,除非使用繼承,否則相關規則可能必須在相關類(DRY)中多次執行。如果您以這種方式進行驗證,則通過您的域進行驗證。
外部驗證(您可以通過DI,工廠,業務層或上下文獲取驗證對象)確保您可以根據上下文替換驗證規則(例如,對於要長期保存的部分流程完成狀態,你可以有一個驗證對象只是爲了能夠保存,另一個來檢查域類是否爲真的有效且可以使用)。您的域類將會更簡單(責任更少,但您必須執行最小限度的檢查,如空檢查,以防止運行時錯誤),並且您還可以重複使用相關類的規則集。通過這種方式,驗證以您的域模型的一個小區域爲中心。 B.t.w.您可以將外部驗證注入到域類本身中,確保類自己進行驗證,但不知道他們正在驗證的內容。
雖然無法對驗證應用程序塊進行評論,但您始終必須權衡利弊對比,從未有一個有效的解決方案。
+1 [Martin Folwer提到](http://martinfowler.com/bliki/ContextualValidation.html),我們可以認爲驗證是我們需要根據上下文運行的東西。如果我們想把它保留在實體的類中,它可以像'validateForBlahBlah'這樣的方法。 – prograhammer 2015-07-28 21:28:22
首先,我同意@ i8abug。
但我確實想進一步談論架構。這些設計架構中的每一個,如域名驅動,都應該被視爲無非是一個建議,並通過審查來查看。
在每一步中,您都應該問問自己,這個問題的好處和缺點與您的應用程序有關。
很多這些涉及添加大量的代碼和嚴重複雜的項目,沒有什麼好處。
驗證點是一個很好的例子。正如斯特凡所說,單一責任原則基本上說你需要創建一整套其他類,其目的只是驗證原始對象的狀態。很明顯,這爲應用程序增加了很多代碼。也許它是爲你生成的,也許你必須手寫它。無論如何,更多的代碼通常等同於不太健壯,並且等同於更難理解。
分離所有這一切的好處是您可以更換驗證規則。好的。缺點是你現在有兩個文件要查看和創建每個類的定義。即:更多的工作。您的應用程序是否需要更換驗證規則?可能不會。我甚至會打賭說很少。
很坦率地說,如果你沿着這條路走下去,那麼你可以把所有的東西都定義爲一個結構體,並讓所有這些「幫助」類蠕變回來,把驗證,持久性,設置屬性等等當作一個完整的吹課的學生幾乎買不到任何東西。
所有這一切,我傾向於自包含的類。換句話說,他們知道他們的財產如何相互關聯,並知道什麼是可接受的價值。他們也可以對自己和他們的孩子進行操作。換句話說,他們知道他們是什麼。這往往導致簡化的編碼和實施。這也導致瞭解確切地去修改或改變的地方。我真正在這裏做的唯一分離就是實現持久性的控制反轉;這使我可以在運行時交換數據提供者;這是我已經完成的幾個應用程序的要求。
要點是,想想你正在做什麼,並決定是否真的是你的特定情況下最好的方式。所有這些編程「規則」畢竟只是建議。
嗨Arnis。你能否詳細說明在驗證方面「接受價值對象的使用」?你在這裏意味着什麼? – 2011-02-15 02:41:34