抓住領域驅動設計中模型的本質

2021-09-13 12:42:14 字數 1602 閱讀 5910

最近公司安排了實現乙個需求。

要給不同層級的部門,分配個「審批人」的角色。有的部門分配,有的部門不分配。在實現審批功能時,讓單據所在部門設定的審批人來審批。

如果這個部門沒有審批人,就往上追這個部門的父部門,父部門有審批人,就呼叫這個審批人,父部門沒有,就再往上追,到公司這一層肯定會有乙個審批人。

但是,所有的部門按業務方向分為前台、中臺、後台三種。還可能會為這三個方向分別安排乙個審批人。

如果查詢審批人的過程中,查到了一級部門(公司層級緊下面一層)還沒有審批人,還要查詢業務方向的審批人。如果業務方向也沒有審批人,才會去找公司的審批人。

但是業務方向只和一級部門有關,如果一級部門是前台,那這個一級部門下的所有子部門都是前台。

現有的資料模型如下:

根據現有規則,對審批人查詢流程總結如下:

1,先找單據所在部門(下稱部門a,這裡假設它不是一級部門)的審批人,若找到,跳出查詢流程;若找不到,則查詢部門a的上級部門。

2,找到a的上級部門b,判斷b是否設定了審批人,若找到,跳出查詢流程;若找不到,判斷b部門是否是一級部門。

3,如果b部門不是一級部門,跳到第2部,繼續向上找;如果b部門是一級部門,判斷b部門是哪個業務方向。

4,如果業務方向上有審批人,跳出查詢流程;如果沒有,去查詢公司的審批人,公司一定有審批人,如果沒有,拋錯。

聽運營人員講完現有模型,隱隱感到不安。按照現有模型去做的話,不僅有很多的邏輯判斷,而且會有高耦合的硬編碼。如,對一級部門的判斷,對業務方向的判斷等。

對於領域驅動設計人員來說,如果是做新東西,最重要的工作就是做出乙個符合業務本質的領域模型;那如果已經有了模型,就應該分析這個模型是否抓住了本質。

如果模型複雜度比較高,而業務邏輯並沒有那麼複雜的話,通常就是模型不合理,導致的邏輯複雜。

那我們來判斷業務方向到底是不是部門的屬性。在資料表裡,由於是關係型資料庫,所有的部門都會有乙個業務方向字段。

比如在部門樹里,乙個部門c,向上追到一級部門是d,那麼d部門是什麼業務方向,c就是什麼業務方向。

也就是說,業務方向屬性,只對一級部門有效。對於一級部門的所有下級部門是無效的。那其實業務方向就不是乙個部門的屬性。

它其實應該是乙個隱藏的級別,見下圖:

由於圖2所表示的部門樹並非完全真實的部門級層關係,但資料可以完全**於真實的部門樹。所以我給它起了個名字叫「影子部門樹」。

在真實部門樹發生變動時,重新生成影子部門樹,然後把審批人,掛在影子部門樹上,就可以把邏輯簡化成如下:

1,先找單據所在部門(下稱部門a,這裡假設它不是一級部門)的審批人,若找到,跳出查詢流程;若找不到,則查詢部門a的上級部門。

2,找到a的上級部門b,迴圈執行查詢審批人的操作。

這樣設計的話,避免了很多無用的概念和邏輯。 如果在最初設計資料模型時就能抓到模型的這種本質的話,那節省的人力物力不是只使用一些設計原則和快速框架能比擬的。

畢竟這是業務層級的設計。

這也體現了領域驅動設計的重要性。架構人員應該培養自己對模型本質的敏銳的直覺。

DDD 領域驅動設計 領域模型中的使用者設計

驗證 根據 userid 判斷此使用者是否擁有部落格。許可權 根據當前 loginname,判斷此使用者是否擁有審核許可權。public int userid public string userloginname public string userdisplayname public strin...

領域驅動設計系列 二 領域模型

領域驅動設計裡有很多東西,我們可以應用在各種各樣的開發模式裡,所以接下來說的一些東西,我們可以部分使用。說道領域驅動的領域,大家肯定就要開始說bounded context,聚合,聚合根,容易讓大家搞糊塗。我覺得先拋開這些概念,後面再來說如何設計聚合,先簡單來說。過去,我們在多層設計裡定義了很多mo...

DDD領域驅動設計 充血模型 貧血領域模型

最早廣泛應用源於ejb2,最強盛時期則是由spring創造,把 分離到不同的物件中 貧血領域模型是乙個存在已久的反模式,它不是個好東西。它完全和物件導向設計背道而馳。物件導向設計主張將資料和行為繫結在一起,而貧血領域模型則更像是一種面向過程設計。貧血領域模型的根本問題在於,它引入了領域模型設計的所有...