博碩文化

協作軟體CollabOvation專案的開發團隊第一次實作DDD,一開始便偏離了正確的道路,使得模型愈來愈含糊不清。會發生這種情況是因為他們不理解戰略設計,連最基本的概念都沒有。其實大多數的軟體開發人員都是把焦點放在實體(Entity)或值物件(Value Object),目光無法放遠、看不見全局,把真正重要的核心領域概念跟一般業務混淆在一起,以至於原本應該分開的兩個模型合在一起了。很快他們就感受到下圖反映的設計問題,重點是,他們沒有達到實作DDD的目標。

由於團隊不了解戰略設計的基礎,導致協作模型的概念一團糟,其中虛線圈起來的,就是有問題的部分。

此時SaaSOvation團隊中有些人說道:「是不是因為這套軟體的協作概念,與使用者(User)和權限(Permission)緊密耦合(tightly-coupled)?我們必須查出誰做了什麼事。」資深開發人員則表示,團隊需要注意的不僅僅是使用者與權限的耦合問題:「畢竟論壇(Forum)、發表文章(Post)、討論(Discussion)、行事曆(Calendar)還有行事曆項目(Calendar Entry),全都需要與某種協作物件建立耦合關係。這才是真正的問題,根本原因在於用語錯了。」接著這位開發人員向團隊成員說明,論壇、發表文章、討論等等全都用了錯誤的通用語言。使用者與權限與協作無關,也與協作使用的通用語言不符。使用者和權限是與安全性有關的概念,也就是身分與存取。既然是「協作情境」(Collaboration Context),那麼,在協作領域模型所處的Bounded Context內,就應該使用與協作相關的用語,但現在並非如此。「真正的重點應該在協作概念上,像是『發文者』(Author)與『版主』(Moderator),這些才是在『協作情境』中要使用的正確概念與用語。」

基本上,SaaSOvation公司這群開發人員一開始就不知道「使用者」與「權限」跟協作軟體無關。雖然一套軟體一定會有「使用者」而且也需要「權限」管理,才能知道誰可以做什麼事情;但「協作軟體」更應該著重在使用者的「角色」上,而非這個人是誰以及這個人能夠做什麼事情。然而,目前這個協作模型完全是以使用者與權限的概念為中心,要是哪天使用者與權限的管理和運作上改變了,那麼很多模型(甚至可能是全部模型)都會受到波及。這個問題事實上已經迫在眉睫了,團隊正打算從以權限為中心的管理機制改為以角色為中心的存取管理機制;當這個決定做下去之後,他們就會更清楚戰略建模出現問題。

現在團隊知道論壇功能的重點不應該是誰可以發表文章、或是什麼情況下可以這樣做,論壇只需要知道「發文者」在做這件事情就好。團隊現在弄清楚了,判斷誰可以做什麼事情是另外一個模型的工作,作為核心的協作模型只需知道已經決定好某個操作要授權給誰(角色)。對於論壇來說,只需要知道發文到討論串的人是「發文者」角色。對協作模型的Bounded Context─也就是「協作情境」而言,論壇和發文者顯然是情境中會使用的通用語言。至於使用者、權限、角色等等概念,又是另一個完全不同的情境用語了,不能跟「協作情境」中的詞彙混在一起。

從開發團隊的視角來看,把使用者、權限、角色等分割為另一個模型,然後在同一個Bounded Context中,劃分出邏輯上的「安全性子領域」,乍看似乎沒錯,因此很容易就會導出這樣的結論:只需要解決使用者與權限的緊密耦合問題。然而,最佳建模策略之所以如此重要,是因為團隊下一個核心領域專案也一樣有以角色為中心的存取需求,並且各領域依賴於領域所屬的角色。很顯然,使用者與角色是屬於支援或通用子領域的概念,未來在整個公司甚至面對客戶(customer-facing)都能夠發揮作用。

因此,採取更積極的方法來建立清晰簡潔的模型,可以幫助開發團隊避免許多潛在問題,否則很有可能會把這個專案滾成一坨大泥球(Big Ball of Mud)。雖然在DDD建模當中,模組化(modularization)確實是一項重要工具,但問題的根本原因不在於沒有把使用者與權限模組化,而是使用了錯誤的情境用語。

幸好資深開發人員對此非常警覺,要是沒人發現,思考很容易愈來愈偏,導致情況愈來愈混亂、甚至可能變成一場災難。等到團隊要對另一組非協作的概念進行建模時,核心領域會變得更模糊,最後產出一個含糊不清的模型,也無法在程式碼中看到協作情境的通用語言。因此,團隊首先必須搞清楚他們開發的業務領域、子領域以及BoundedContext的範圍,這樣才能避開戰略設計對立面的陷阱,不至於落入「大泥球」的下場。換句話說,團隊需要先建立起戰略建模的思維模式。

Bounded Context的重要性

「Bounded Context」意指一個明確的邊界,領域模型存在這個範圍內,而領域模型則是透過軟體模型來表達通用語言。邊界之所以需要存在,是因為模型各自的概念、屬性(property)、行為都有其特殊意義。如果你是負責建模的團隊成員,你一定要了解情境中每個概念的確切意義。

我們也常看到,兩個明顯不同的模型有著明明一樣或類似名稱的物件,但卻代表不同含義。當我們分別對這兩個模型畫下明確的邊界,就可以知道這些概念在不同邊界內各自代表什麼意義;因此,「Bounded Context」主要是指「語義上的分界」。讀者應該依據這些論點,檢驗自己對於Bounded Context概念的理解和運用是否正確。

現在,讓我們回到圖片上,快速檢視一遍SaaSOvation的協作軟體開發團隊針對建模挑戰提出解決方案。

在「協作情境」中,領域專家不會把使用協作功能的人描述成「有權限的使用者」,而是會根據他在該情境中扮演的角色,如「發文者」、「擁有者」、「參與者」或是「版主」來指稱;雖然當中會有使用者的一些聯絡資訊,但不會是全部,這些是屬於「身分與存取情境」中的「使用者」資訊,在該情境中,使用者物件會帶有使用者名稱以及相關個人資訊,像是各種聯絡方式。

但是「發文者」物件也不是憑空產生的,每一個協作者都需要事先經過認證設定;我們會在「身分與存取情境」中進行驗證,確認使用者被指定扮演的角色,在執行安全驗證的過程中,驗證資料的屬性會隨著請求一同發送到「身分與存取情境」。要建立新的協作者物件,像是新增「版主」角色時,需要一部分的「使用者」屬性並指定一個「角色」(Role)名稱。這裡的重點是:兩個不同的概念,同時存在著異同之處,而它們之間的差異要透過Bounded Context來判斷。(本文摘錄整理自《實戰領域驅動設計》第二章,博碩文化提供)

圖片來源_博碩文化

 書名  實戰領域驅動設計(Implementing Domain-Driven Design)

Vaughn Vernon/著;錢亞宏/譯

博碩文化出版

定價:1,280元

圖片來源_Vaughn Vernon

 作者簡介 

Vaughn Vernon

Vaughn Vernon是一名資深的軟體工程師,在軟體設計、開發與架構方面擁有超過25年以上的豐富經驗,提倡將創新的方法運用於實作當中並簡化軟體設計。自1980年代以來,他一直在從事物件導向語言的程式設計,並於1990年代初期還以Smalltalk作為領域建模工具的時期開始就致力於領域驅動設計。他在國際間提供軟體開發的諮詢與授課服務,並在許多國家開設「實戰領域驅動設計」的訓練課程。

熱門新聞

Advertisement