l

2022年3月18日 星期五

領域模型 VS 資料模型

March 18 15:36~17:02

 

截圖 2022-03-18 下午4.49.39

▲看板桌遊

 

問題

昨天在北科上軟體架構請學生練習Event Storming,有學生問Teddy:「域驅動設計強調要建立域模型,但我不太清楚領域模型 (domain model) 與資料模型 (data model) 有什麼不一樣?領域模型裡面物件的屬性,和資料模型的資料欄位不是很類似嗎?

領域驅動設計強調透過開發人員與領域專家共同合作建立領域模型,而不要採用傳統資料驅動或是使用者介面驅動的方式來開發軟體。道理很簡單,但領域模型與資料模型到底有何不同,許多人並無法分辨。

今天來談這個問題。

***

資料驅動

請看圖1和圖2畫面,你會覺得這是兩個不同的軟體,還是同一個軟體?

 

截圖 2022-03-18 下午4.00.07

▲圖1:ezKanban畫面

 

截圖 2022-03-18 下午4.00.17

▲圖2:看板桌遊畫面

 

如果從「資料驅動」的角度來看,看了這兩個圖,大部分的人會覺得這是兩個不同的系統。以圖2為例,畫面上有以下不同種類的卡片:

  • 事件卡片:Day 9那張卡片代表event card,它的背面也有資料。你可能在資料庫中設計一個event_card table來儲存事件卡片的資料。
  • 標準卡片:S開頭的卡片,如果設計一個standard_card table來儲存它的資料,則該table欄位可能包含analysis_total_work, analysis_done_work, dev_total_work, dev_done_work, test_total_work, test_done_work, day_deployed, day_ready, lead_time, subscribers等欄位。
  • 固定交期卡片:F1與F2卡片,這兩張卡片的內容與標準卡片很像,感覺可以把資料放在standard_card table,只要多增加一個card_type欄位來區分卡片種類是標準卡片還是固定交期卡片即可。
  • 技術卡片:和前兩種卡片也很像,可以把資料放在standard_card table

看板遊戲還有骰子、Ready、Analysis、Dev、Test、Ready to Deploy、Deployed等固定的工作階段,也要設計相對應的資料庫表格來儲存這些資料。

***

至於圖1的ezKanban,卡片內容記錄的資料和看板桌遊不一樣,所以可能需要一個card table來紀錄資料,裡有可能有cardId, workflowId, laneId, description, deadline, note, estimate, assignees 等欄位。很明顯地,兩個系統的資料模型並不一樣。

***

領域驅動

如果從領域驅動的角度來看,ezKanban與看板桌遊廣義來看都屬於「看板」這個問題領域,所以它們的商業邏輯與行為很可能絕大部分是相同的。例如,從看板系統的三個核心原則來看:

  • 視覺化:視覺化團隊的工作流程與工作項目
  • 限制WIP:限制工作階段的WIP (Work In Progress)
  • 管理工作流:可以測量Lead Time與Cycle Time,看到被阻礙的工作。

這三個特性,在ezKanban與看板桌遊都成立。從領域驅動的角度來看,兩者可以視為同一個系統,共享相同的領域模型,請參考圖3,只不過前端顯示方式不同。

 

   截圖 2022-03-18 下午6.42.55

▲圖3:ezKanban領域模型,看板桌遊也可以共用此領域模型

 

***

看到這裡鄉民們可能會想:「兩個系統的資料模型明明就不一樣啊,硬要說它們是同一個系統,那麼要如何儲存兩者的資料,資料庫要怎麼設計?」

很簡單,如果把看板桌遊視為ezKanban的一部分,那麼看板桌遊的事件卡片、標準卡片、固定交期卡片、技術卡片,就全部都是ezKanban裡面Card這個Aggregate的一種特例。只要將看板桌遊的卡片所需要的資料以JSON的格式存入Card的note欄位即可,如圖4所示。

 

截圖 2022-03-18 下午4.30.04

▲圖4:標準卡片S9所需的資料,用JSON格式表達

 

***

結論

ezKanban因為採用領域驅動設計的方式開發,因此將看板桌遊視為看板系統的一種特例,只有前端顯示桌遊的React程式不同,後端絕大部分的功能都是一樣,不需重複開發。

但如果從資料驅動設計使用者介面驅動設計的角度來看,後端就非常有可能變成兩個完全不同的系統,產生很多重複的工作。

***

友藏內心獨白:不管是單體還是微服務,有複雜邏輯的系統還是採用領域驅動設計比較好。

10 則留言:

  1. 如果是先設計看板桌遊,然後才設計 ezKanban 會得到相同的結果嗎?

    回覆刪除
    回覆
    1. 如果是我來設計,會,但可能需要重構的程式碼會比較多一點,因為是從special case轉成general case。

      刪除
    2. 您來設計會,因為您是專家本人…XD

      刪除
    3. 我只能代表我,我無法代表其他人啊 XD

      刪除
  2. "將看板桌遊的卡片所需要的資料以JSON的格式存入Card的note欄位即可"
    總感覺 怪怪的

    把一堆領域邏輯的欄位 用 json 放入到 資料庫的單一欄位
    這樣 schema失去意義了吧

    怎不說把所有 欄位 都簡化為 一個欄位...

    回覆刪除
    回覆
    1. 不會怪喔,還有人出paper介紹這種擴充方式,你可以去找來看。

      刪除
  3. Teddy你好,想請問是哪篇paper提到此概念呢?想了解一下,感謝

    回覆刪除
    回覆
    1. 這篇: A new approach to storing dynamic data in relational databases using JSON

      刪除
  4. notion 是否是在這個 domain model 下,才能有那麼多互換的前端顯示、輸入模式?

    回覆刪除