1. 程式人生 > >關於領域驅動(domain-driven desgin, ddd)開發 概述

關於領域驅動(domain-driven desgin, ddd)開發 概述

關於領域驅動開發,想寫一個系列的文章。分享一下近兩年在專案中運用ddd的經驗,和自己的一些理解,教訓。

第一篇文章先概述一下。

領域驅動設計 domain-driven design. 簡稱ddd。

在島國這兩年是一個比較火的名詞,明明是一個有著多年曆史的概念,不知道為什麼過了那麼久突然流行了起來。天朝的情況不是很瞭解,不過無所謂啦,思想啦理論啦不存在國界的!


什麼是ddd?

這一個概念來自Eric Evans所著的<domain-driven desgin>一書。(P.S. 此書極為枯燥,而且理論繁多,閱讀的障礙很大。)書中並沒有很正規地用下定義來描述各種名詞,所以個人認為導致了對領域驅動究竟是什麼的的多種解釋。

在這我說一下自己的理解(僅限於自己理解)


領域(以下都稱domain)指需要解決的現實問題(業務),為了解決現實問題(domain),我們會建立模型(以下稱model)來幫助我們描述與理解domain,從而能夠應對domain。

純理論地說,domain是問題空間,model是解決空間(雖然一點都不好懂)。


比如,要開發一個考勤管理系統,考勤中的一些實際業務如打卡,休假申請就是domain。我們會建立一些model來應對這些domain。比如建立休假申請的model,然後賦予它一些狀態,來描述休假申請這個業務的執行。這種domain與model的對應比較簡單。如何管理考勤,已經有現有的經驗與管理方式,從這個意義上說幫助我們理解的抽象的model已經存在,我們只是為了軟體設計的方便對model在進行加工。

但如果一些複雜的問題,domain與model的關係就會不那麼一目瞭然,比如要評價學生是一個現實課題(domain)。那用學生的考分進行評價就是一種model。


那domain驅動設計,顧名思義,由從domain出發,來設計,建模。

而ddd的大致流程便是

1 理解domain

2 建立應對domain的model (domain model)

3 根據model開發。

另外,ddd中,model一般特指domain model。即剛才說的應對domain的model。



為什麼需要ddd?

這種看似理所當然的設計方式,為什麼要像當作課題一樣提出呢?

1 業務(domain)的複雜性,讓理所當然的事情,做起來不那麼簡單

 沒能完成需求的專案,必定是失敗的。(當然專案的失敗也有可能是其他原因,這不屬於ddd討論範疇。)當domain十分複雜時,我們必須有好的方法去理清,理解domain,並根據他來開發。

2 人們設計時當然是離不開model的。但model其實也是分好幾種。比如domain model(領域模型)與data model(資料模型)。

 有時候會更傾向於對data model的思考,比如拿到需求就開始搞資料表設計,並不是說data model不好或者不重要,而是跳過了domain model,直接考慮data model,容易導致建立的model沒能很好的應對實際的domain。這個以後會重點講!

3 軟體的開發,縱向分工過多,每一次分工都會建立新的model來教給下層的開發人員來實現,結果導致開發人員對domain的理解不正確,最終導致產品不能實現業務。

從前(現在也可能)的軟體開發行業,存在各種外包。有的軟體公司只負責設計,然後把設計文件人給其他公司編碼。這種現象在島國的軟體開發行業非常常見,以至於島國的網際網路行業。。。大概的流程會是需求分析,上流設計,詳細設計,編碼。

綜上,ddd所提倡的是,不要建立過多的model,而是建立與domain最接近的domain model,然後根據domain model來進行開發。model必須儘量反應實際的domain。


ddd真的有效嗎?

這個問題非常難。。。如果你去網上搜一下ddd的成功案例。結果會是。。。(應該沒有)

也有種說法是ddd所追求的是對domain model的不斷深化改造,所以在應用ddd開發的人們眼裡,達到什麼程度算是成功是不明確的。

從本人目前的工作經驗上說,有專案運用了ddd,是否實現了ddd的精髓有待商榷,但開發者有了共同的設計思想和交流語言,使設計容易傳達,說了更明顯一點,就是程式碼容易讀,容易修改。但有個人覺得這種效果其實需要非常多的前提,以後的文章會進一步討論。

另外,有時候理論是用來解決某一些特定問題的。比如ddd提倡根據domain model來開發,防止對需求的認識偏差。但如果專案開發中,開發人員的需求的理解偏差不是一個很大的問題,那ddd在這個問題上就沒有太多發揮餘地了(個人認為)。當然除了這個ddd當然還有其他的作用,以後會介紹。

但底線是,我們可以通過學習ddd所提倡的思想和一些設計手法,幫助我們做一些更好的設計。



今後的內容

之後會寫更多ddd的內容。順序的話並不按照domain-drive design書中的章節(比如準備先講戰術,再講戰略)。而是類似於還原自己如何去接觸ddd的過程,這樣可能更容易理解。對於想學習應用程式架構,程式設計的人來說,可能是一種比較自然的理解/學習過程

目前能想到的大概有

ddd的戰術: 分層設計

ddd的戰術: entity, VO, aggregate, repository

ddd的戰術: 如果沒有domian model程式會是怎樣的?

ddd的戰術: domain event

讓ddd發揮自己的優勢,CQRS!

ddd的戰略: bounded context


另外列一下推薦的參考書

implementing domain-driven desgin (比較通俗易懂)

domain-driven desgin distilled

domain-driven desgin (如果你想抱著試試的態度,千萬別先讀這本書,過早嘗試會讓你對ddd的興趣喪失殆盡)