32

我想學習領域驅動設計(DDD),我想我有了基本的想法。但是有一些讓我感到困惑。DDD - 持久性模型和領域模型

在DDD中,持久性模型和領域模型是不同的東西嗎?我的意思是,我們設計我們的領域和類只考慮領域問題;沒關係。但在此之後,當我們構建存儲庫或任何其他數據持久性系統時,我們是否應該在持久層中創建另一個模型表示以用於我們的模型?

我在想我們的領域模型也用於持久化,也就是說我們的存儲庫從查詢中返回我們的領域對象。但是今天,我讀了這篇文章,我有點糊塗了:

Just Stop It! The Domain Model Is Not The Persistence Model

如果這是真的什麼是有獨立的持久性從域對象物體的優勢在哪裏?

+2

這是我寫在這個確切的主題上的文章:http://enterprisecraftsmanship.com/2016/04/05/having-the-domain-model-separate-from-the-persistence-model/ – Vladimir

回答

41

想想這樣,領域模型應該不依賴於任何東西,並且其中沒有基礎結構代碼。領域模型不應該是可序列化的或從一些ORM對象繼承,甚至不能共享它們。這些都是基礎設施問題,應該與域模型分開定義。

但是,也就是說,如果您正在尋找純粹的DDD,並且您的項目的價值在於初始開發速度的可擴展性和性能。很多時候,將基礎設施問題與「域模型」混合在一起可以幫助您以可擴展性爲代價實現速度的大幅提升。關鍵是,你需要問自己:「純DDD的好處是否值得開發速度?」。如果你的答案是肯定的,那麼這裏是你的問題的答案。

讓我們從一個例子開始,你的應用程序以一個領域模型開始,而恰恰恰恰相反,數據庫中的表格恰好與你的領域模型匹配。現在,您的應用程序突飛猛進地增長,您在查詢數據庫時開始遇到性能問題。您已經應用了一些經過深思熟慮的索引,但是您的表增長得非常快,以至於您可能需要對數據庫進行非規範化處理以保持速度。因此,在dba的幫助下,您提出了一個新的數據庫設計來處理您的性能需求,但現在這些表與以前的方式大不相同,現在您的域實體塊分佈在多個表中而不是每個實體的一張桌子。

這只是一個例子,但它演示了爲什麼您的域模型應與持久性模型分開。在這個例子中,你不想分解你的領域模型的類,以匹配你對持久性模型設計所做的改變,從根本上改變領域模型的含義。相反,您希望更改新持久性模型和域模型之間的映射。

因爲保持這些設計幾個好處分開,如可擴展性,性能和緊急分貝變化的反應時間,但你應該對其進行權衡前期開發成本和速度。通常,從這種分離水平中獲得最大收益的項目是大型企業應用程序。

更新評論員

在軟件開發的世界裏,有一種可能的解決方案第N個號。正因爲如此,靈活性與開發速度之間存在間接的反向關係。作爲一個簡單的例子,我可以將邏輯硬編碼到一個類中,或者我可以編寫一個允許將動態邏輯規則傳遞給它的類。前者的選擇會有更高的發展速度,但其代價是靈活性較低。後一種選擇將具有更高程度的靈活性,但代價是開發速度較低。這在每種編碼語言中都適用,因爲總有第​​N種可能的解決方案。

許多工具可幫助您提高初始開發速度和靈活性。例如,一個ORM工具可能會增加數據庫訪問代碼的開發速度,同時還可以靈活地選擇ORM支持的任何特定數據庫實現。從您的角度來看,這是在時間和靈活性兩方面的淨收益減去工具的成本(其中一些是免費的),根據開發時間相對於工具的價值的成本,這可能會也可能不值得業務需要。

但是,對於這段對話中,編碼風格,它基本上是領域驅動設計是什麼,你必須考慮到它採取寫你正在使用的工具的時間。如果您要編寫該ORM工具,或者甚至編寫數據庫訪問邏輯,以支持該工具爲您提供的所有實現,則需要花費比編寫您計劃的特定實現時間更長的時間在使用。

綜上所述,工具可以幫助你來抵消自己的時間來生產和價格的靈活性,往往通過分發當時大家誰購買工具的成本。但是,包括使用工具的代碼在內的任何代碼仍將受速度/靈活性關係的影響。通過這種方式,域驅動設計比您將業務邏輯,數據庫訪問,服務訪問和UI代碼聚攏在一起,但需要花費時間進行生產,可以提供更大的靈活性。域驅動設計比小型應用程序更好地爲企業級應用程序提供服務,因爲企業級應用程序的初始開發時間相對於業務價值而言往往具有更高的成本,並且因爲它們更復雜,所以它們也更容易變更,需要更大的靈活性降低時間成本。

+1

This是一個很好的答案,但你一直重申我們需要「選擇」 - 我希望你能澄清爲什麼你認爲我們不能擁有我們的蛋糕並且也不會吃它?在我看來,如果有更好的工具來促進這種發展,初始發展的速度不應該是一個因素?這些工具是不是還沒有? –

+1

我想看到對此的評論。 – Seralize

+0

爲評論者添加更新以回答您的問題。 –

9

在DDD中,持久性模型和領域模型有什麼不同嗎?

是的,但這並不一定意味着一組不同的類來明確表示持久性模型。

如果使用關係數據庫進行持久化,那麼像NHibernate這樣的ORM可以通過映射到域類來處理持久模型。在這種情況下,沒有明確的持久性模型類。這種方法的成功取決於ORM的映射能力。例如,NHibernate可以通過component mappings支持中間映射類。這允許在需要時使用顯式持久模型類。

如果使用文檔數據庫進行持久化,通常更不需要持久性模型,因爲域模型只需要可序列化以便持久化。

因此,使用ORM映射到域模型時無法實現的複雜映射時,請使用顯式持久性模型類。領域模型和持久性模型之間的區別仍然與實現無關。

+0

嗯,所以我只要我能以正確的方式處理持久性,就可以使用相同的類。當它還不夠時,我可以重新考慮並添加一些新的類而不是域類來實現持久性。我是否正確? – ayk

+0

是的,特定於持久性的類可以有多種風格。它們可以是數據庫和域之間的簡單DTO,也可以是現有映射基礎結構(如NHibernate)的一部分。 – eulerfx

+0

我想,現在很清楚,非常感謝您的關注和幫助。 – ayk

4

在DDD,是持久化模型和領域模型不同的東西?

在DDD你有域模型。而已。如果在存儲庫內部,您將直接持續存在域模型或將其轉換爲持久模型,然後再堅持到您!這是設計和設計的問題。

正如其他喉管指出,每個選項都有其優點和缺點。看看這個answer其中我詳細介紹了其中的一些。

+1

我讀了很多關於DDD的文章,但你的簡短描述是最好的。謝謝。 – user2980426