領域驅動設計(DDD) 請先搞清楚一些概念

2022-08-30 14:15:13 字數 3325 閱讀 4159

一般我們開始開發乙個商業系統都需要做什麼?讀需求文件去查詢功能點,拆解任務。多數情況下,拆解專案是為了評估工作,做評估、分配任務到個人、設計資料庫結構,然後就開始了coding。

所以,這種方式怎麼樣?我們是否已經做的很好了??

想想近幾年通過這種方式做的專案是否都有下面一些問題呢?

你的專案在一些地方有著相同的實現

對同乙個東西有著不止乙個的物件

有些物件的屬性並不是真實的屬性

各個物件相互之間沒有或者有很小的關聯

看看你的專案是不是很難理解專案的真正意圖

我肯定你經常遇到上面的問題,你知道為什麼會出現這些問題麼?原因是傳統的方式指導我們自下而上的設計整個系統,而不是嘗試著自上而下的設計系統。當你設計乙個系統,你需要整個程式將要做什麼,客戶想要達到什麼樣的目標,那麼從頂層目標開始設計會讓你最終達到預定的目標。

但是當你從底層開始設計的時候,你會從細微處開始設計,你只有一點或者沒有任何關於頂層怎麼使用或者頂層的功能到底是怎樣的。

你是否聽說過有些開發者說他們對整個領域的知識並不清楚,那是必然的,因為整個程式的設計並不能體現整個領域,並且開發者只了解他們工作的那個部分,這是很悲催的事情。。。

那麼,傳統的方式-「資料庫優先的開發方式」應該被遺棄麼?並不是這個意思,但是當你面對乙個複雜的系統,這種自下而上的設計並不能提供乙個好的物件導向的處理方式。

那麼,好的解決方案是什麼?

解決方案就是 ddd(domain driven design)。

領域驅動設計(domain-driven design 縮寫ddd)不是一種技術或者方法,ddd提供了一種實踐性的指導原則,用來解決和加速處理複雜領域的軟體專案 -維基百科。

理解領域(domain)

通用語言(ubiquitous language)

上下文和有界上下文(contexts and bounded context)

實體和值物件(entities and value objects)

聚合和聚合根(aggregates and aggregate roots)

持久化透明(persistence ignorance)

倉儲(repository)

領域服務(domain service)

本文只是對這些感念進行理解,並不提供任何可用的**。

領域是一定範圍內的知識、活動、影響。使用者用程式去解決、處理的領域就是軟體的領域。

領域就是乙個概念,你能說出你現在做的程式的領域是什麼?,你能說說優酷**的領域是什麼麼?

本文就利用生活中真實的例子來讓你體驗怎麼用領域來驅動你去分析你的專案。這個例子可能並不與開發有關,但它們對讓你適應上而下的去思考是很有幫助的,同時也過一遍ddd的技術要點。

如果說你要蓋一棟房子,那麼你需要以下的東西

那麼你的領域是什麼呢?

領域是房子麼?可能,但是你應該知道,如果你把房子作為你的領域,那麼你可能會忽略很多的小的需求。你設計的房子必須設計那裡是讓人住的。那麼,一般而言的「房子」可能會讓我們忽略一些細節,所以,我們應該縮小我們的領域,那就是「民房」。

那麼,當你和建築工人或買房子的人說起你設計的房子時,你所說的「民房」就可以很容易的被人理解了。當承包商告訴你要設計乙個6層每層4套房子的時候,在語言上你是否稍微修改了一下呢?現在如果你讓建築工人到乙個地方建「房子」,他們可能並沒有考慮到一些「民房」的一些特性。但是如果你說了「民房」呢,他們肯定會做出合理的分析。

這就是我們將要說到的「通用語言」

概念很簡單,程式設計師和銷售應該公用同一種兩個人都理解的語言,更重要的是,應該使用商業術語而不是技術術語。

例1:錯誤的語言:

小臥室的長寬比應該是4:3

正確的語言:

兒童臥室長度因該是20尺,寬度應該是15尺。

從這可以看到,對於房主來說「小臥室」,「長寬比」這些都屬於技術術語,對他們來說兒童房、客廳、起居室等才是更易理解的詞語。很明顯尺寸對房主來說更為有意義。

例2:來看看軟體上的一些例子。

錯誤的語言:

在搜尋功能上,我們應該考慮sql server的「詞幹分析器」和「同義詞庫」來讓我們的搜尋更合理,另外我們也應該新增排除詞,讓搜尋更精確。

從這裡可以看到,如果你的領域專家可能不是個技術型,那麼他很有可能不理解「詞幹分析器」和「同義詞庫」等。

正確的語言:

你能看到這些語言的不同之處麼?乙個正確的語言可以讓圈內的所有人都以相同的方式理解這些觀點。

我們再說說「民房」吧。如果你將設計民房的所有事情當作乙個任務並放在一起處理的話,你認為這樣明智麼?很明顯,如果你將這些作為乙個工作單元的話,你可能會錯過一些東西。設計乙個房子有很多相關聯的設計,例如,你需要考慮通風,多功能,停車空間,社群等。

正如你所看到的,不同的上下文就出現了,這就是「上下文」和「有界上下文」出現在領域驅動設計的原因了。

乙個有界上下文可以是乙個很小的程式,包括他自己的領域,自己的**和自己的儲存機制,在乙個上下文裡,他們應該在邏輯上一致,每個有界上下文應該獨立於其他的有界上下文。

考慮一下電商系統,最初你可以認為他是乙個商店上下文,但是你看的更細點,你會發現其他的上下文,例如:庫存,物流,賬戶等。

合理的拆分乙個大型的有界上下文可以讓你的應用程式模組化,並且讓你區分不同的關注點,而且讓應用程式更易於管理和公升級。每個有界上下文都有相應的責任和操作。合理的上下文劃分可以讓我們更容易的找到邏輯所在的位置,從而避免「大泥球」。

大泥球是乙個不規則的、雜亂的、鬆散的泥巴,這類系統是典型的高度重複,快速修復,無意義增長的系統。混亂的訊息傳遞,在乙個地方幾乎所有的重要資訊都是全域性的和重複的,所有的系統架構都可能沒有被很好的定義。

我們的目標是避免所有的bbom

我們還來說說「民房領域」吧,我們有幾個有界上下文:

詳細說一下「套房」吧,套房是由不同的房間組成,每個房間又有不同的門窗。那麼現在關於屋裡面的窗戶就有兩個問題了:

問題1:你可以想象出來沒有屋子的窗戶麼?

問題2:如果乙個窗戶沒有了容納他的屋子,那麼它有沒有唯一的標識?

回答上面的問題會揭示出ddd中下面的概念:

實體(entity)

值物件(value object)

聚合和聚合根(aggreates & aggrate root)

「這是我的實體,那裡還有許多,但是這個是我的!」

定義實體的關鍵是實體是有「唯一標識」(identity)的,唯一標識在系統中標識,無論兩個實體是多麼的相似,他們都是不同的實體。

例如:你家的臥室

部落格網的文章

部落格網的使用者

定義值物件的關鍵是值物件沒有「唯一標識」,這樣說可能有點簡單,????

上面給出的例子中:

當資料改變時,所有相關的物件被看作乙個整體。

所有的外部資料訪問都需要通過同乙個根節點進入,這個根就是根節點

DDD領域驅動設計

公司裡面敏捷專案要講ddd領域驅動設計,加緊學習了一下,找了一些資料研究。eric evans的 domain driven design領域驅動設計 簡稱ddd,evans ddd是一套綜合軟體系統分析和設計的物件導向建模方法,本站jdon.com是國內公開最早討論ddd 之一,可訂閱 ddd專題...

DDD(領域驅動設計)

domain 領域 driven 驅動 design 設計 由eric evans最先提出,目的是對軟體所涉及到的領域進行建模,以應對系統規模過大時引起的軟體複雜性的問題。整個過程大概是這樣 開發團隊和領域專家一起通過 通用語言 ubiquitous language 去理解和消化領域知識,從領域知...

DDD領域驅動設計

極客時間學習筆記 為什麼微服務設計的時候需要ddd?1 軟體架構模式演進的三個階段 第一階段是單機架構 第二階段是集中式架構 第三階段是分布式微服務架構 2 在單機和集中式架構這兩種模式下,軟體無法快速響應需求和業務的迅速變化,最終錯失發展良機。3 微服務拆分困境產生的根本原因就是不知道業務或者微服...