摘要:[DDD] DDD經驗分享 (上)
前言
身為一個開發人員,應該會有聽過「軟體開發流程」、「領域驅動開發」等等,這些開發技術名詞。但是...開發人員心底話,包含我自己都覺得:資料文件都寫的跟天書一樣,模模糊糊的、專案壓力下趕工都來不及了,誰有空搞這些的東西。
今天要來扭轉這種印象,讓開發人員搞懂「軟體開發流程」、「領域驅動開發」這些開發技術。並且以自身的開發經驗,說明這些開發技術該在哪用、怎麼用。讓專案的開發不再是無中生有,而是一個循序漸進的過程慢慢「長」出來的。
*在文章開始之前,一定要先提一個最重要的重點:開發技術沒有最好的只有最適合的。硬搬教條式的項目到自己團隊中,讓成員做的很累,這樣一定不會長久。例如用來當作本篇文章議題內容的軟體開發流程,也是採納各家技術資料,最終經過調整、整合之後才得到的成果。依照團隊開發習慣,去融會貫通各種開發技術的長處,才是能夠走長遠的道路。
定義
首先我們先來為今天要講解的兩個開發技術:「軟體開發流程」、「領域驅動開發」,做一個簡單的說明跟定義。
「軟體開發流程」定義「做甚麼」
「軟體開發流程」是某某大老提出來的(我也不知道是誰...)。將開發一個軟體應該完成的工作,切割成為一組有開發優先順序的軟體開發階段。而軟體開發流程的實做模型有很多種,像是:瀑布式、螺旋式....等等。
一個定義清晰的軟體開發流程,就像是一份SOP讓開發人員參考。讓開發人員在每個軟體開發階段,知道現在該做甚麼、下一步該做甚麼。聚焦該做的事、不讓思考發散。簡單的說,軟體開發流程定義做甚麼。
「領域驅動開發」定義「怎麼做」
「領域驅動開發」是Eric Evans提出來的,並且將內容整理成了一本Domain Driven Design。它定義了一套開發用的思考邏輯,用以貫穿整個軟體開發流程。
相信開發人員都有用過很多的開發工具,在每個軟體開發階段裡分析設計系統。例如:Use Case、類別圖、順序圖...。但是說真的,大部分的資料文件,都只有介紹這個階段該用某某工具、圖該怎麼畫。至於圖畫完了再來要做甚麼,每個階段產出怎麼串起來。都寫的有看沒有懂...可以說大部分的資料文件,沒有一個把軟體開發流程工作全部貫穿的思想。在這樣的情況下,每個階段產出就都只是零碎並且不連貫的拼圖碎片,實用的價值大大的降低。
「領域驅動開發」就是要解決這件事。它定義了一套開發用的思考邏輯,貫穿每個軟體開發階段。讓開發人員在每個軟體開發階段,知道現在該怎麼做、接下來怎麼做。簡單的說,領域驅動開發定義怎麼做。
軟體開發流程 – 範例
知道了,軟體開發流程定義做甚麼、領域驅動開發定義怎麼做。本篇文章就以一個簡化的軟體開發流程跟領域驅動開發做為議題內容。說明這些開發技術該如何搭配使用,並且又如何能讓開發工作更輕鬆快速完成。接著就來看看,今天所要說明的,軟體開發流程裡各個軟體開發階段的定義:
需求分析階段 (RA) : 做甚麼
「需求分析階段」主要的工作是收集客戶的需求並且定義專案的範圍。簡單的說,就是要先了解整個專案要做甚麼。
系統分析階段 (SA) : 怎麼做 - 架構設計
「系統分析階段」主要的工作是對客戶的需求內容,提出解決方案並且分析系統架構。簡單的說,就是要先初步的決定怎麼做,並且做好整個系統架構的設計。
系統設計階段 (SD) : 怎麼做 - 模組設計
系統設計階段」主要的工作是對設計完成的系統架構,做每個功能模組的物件設計。簡單的說,就是要開始細部的決定怎麼做,將系統架構內的功能模組做分析跟設計。
系統實做階段 (Implement) : 動手做
「系統實做階段」主要的工作是將完成的系統架構設計,變成實際執行的程式碼。簡單的說,也就是實際動手下去做,把前面幾個階段分析設計出來的架構模組一一的實現。
上列資料是本次議題,用來當作議題內容的簡單軟體開發流程。這個軟體開發流程抽離了專案管理相關的技術細節,只專注在開發人員所應該完成的工作。這樣的抽離解說方式,是希望讓開發人員更專注在開發相關的知識。當開發人員掌握了每個軟體開發階段該完成的開發工作。回頭再學習公司內部使用包含專案管理相關的軟體開發流程,才會有事半功倍的效果。
到了這邊經過簡單的介紹,開發人員應該對於本次議題所使用的軟體開發流程,有一定程度的認識。接著後續的章節,就針對這個軟體開發流程,做每個軟體開發階段的內容說明。
需求分析階段 (RA)
「需求分析階段」主要的工作是收集客戶的需求並且定義專案的範圍。一般會採Use Cases、Prototype等等工具,來完成需求分析的工作。最終將收集完畢的需求資料,整理成一份「軟體需求規格書」。
當然啦...以我碰到的真實狀況,一般都是業務去跟客戶做需求訪談。也不會管Use Cases、Prototype之類的東西,就是單純的先把案子簽下來。好一點的業務,會整理一份寫滿功能的清單,爛一點的就是口頭說案子拿下來了。後續的工作就全部都給開發人員去收尾,做需求分析的動作。其實不管如何,該做的工作還是要做,只是誰做而已。
針對需求分析階段,前面有說過會使用Use Cases、Prototype等等工具,來完成需求分析的工作。這些工具很強而有力,可以幫忙捕捉到客戶的需求。但是實際使用這些工具,會發現捕捉到的只是客戶表面的需求。對於客戶真正要解決問題的相關知識,只能透過開發人員的經驗去做分析設計的動作。
之前有一本「QBQ!問題背後的問題」很火紅,它說明要解決的是問題根源,而不是只處理表面浮現的問題。跟客戶做需求訪談也是一樣,不是單純客戶要甚麼就做甚麼。而是要去了解客戶專業領域的領域知識,針對要專案的內容做訪談,抽取並且封裝領域知識、定義領域名詞。用這些領域知識來理解、解決客戶的問題。這樣才能真正提出客戶所需要的解決方案,解決客戶要解決的問題。這也就是領域驅動開發所提出來的「領域模型」概念。
需求分析階段 (RA) – 領域模型
上圖是一個門禁系統相關的領域模型。它用很抽象的方式描述了在門禁相關領域,所使用到的領域知識、以及專有的領域名詞。我們可以這樣去看這張圖描述的內容:
- 一個門上面會有安裝一部讀卡機。
- 一個門可以讓好幾個使用者通過。
- 一個讀卡機可以控制一個門的開關。
- 一部讀卡機上面會有很多刷卡紀錄。
- 一部讀卡機可以讓好幾張卡片通過。
- 一個刷卡記錄會記錄一個讀卡機、以及一張卡片。
- ......
這個領域模型的建立,是在跟客戶做需求訪談的過程中。了解客戶專業領域的領域知識後,經過抽取封裝領域知識、定義專有的領域名詞...等等步驟,最後繪製而成。透過這樣抽象的物件模型,將客戶專業領域的領域知識,轉化成為可討論、可記錄的模型資料。並且這個領域模型不是一個獨立的工作項目,領域模型要與Use Cases、Prototype等等資料做整合。必須要可以通過領域模型來完整解釋說明,與客戶訪談所記錄下來Use Cases、Prototype這些資料。例如說,某個Use Case內記錄了客戶想要「設定使用者,通過哪個門」,那在領域模型上就要可以透過抽象的物件模型,去找到這樣的抽象描述:「使用者擁有一張卡,它可以使用這張卡,去使用讀卡機把門打開然後通過」。當領域模型可以 通過所有Use Case的檢驗,也就驗證了領域模型的正確性。開發人員就可以安心的將領域模型,帶入下一個開發階段做使用。
待續...
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。