目錄
- 運用領域模型-消化知識
- 有效建模的要素
- 知識消化
- 持續學習
- 知識豐富的設計
- 示例
- 深層模型
運用領域模型-消化知識
非原創,感謝《領域驅動設計》這本書
有效建模的要素
(1) 模型和實作的系結,最初的原型雖然簡陋,但它在模型與實作之間建立了早期鏈接,而且在所有后續的迭代中我們一直在維護該鏈接,
(2) 建立了一種基于模型的語言,隨著專案的進展,雙方都能夠直接使用模型中的術語,并將它們組織為符合模型結構的陳述句,而且無需翻譯即可理解互相要表達的意思,
個人理解:定義專業詞語的字典解釋,保證每個人對每個術語的理解都是一樣的
(3) 開發一個蘊含豐富知識的模型,物件具有行為和強制性規則,模型并不僅僅是一種資料模式,它還是解決復雜問題不可或缺的部分,模型包含各種型別的知識,
(4) 提煉模型,在模型日趨完整的程序中,重要的概念不斷被添加到模型中,但同樣重要的是,不再使用的或不重要的概念則從模型中被移除,當一個不需要的概念與一個需要的概念有關聯時,則把重要的概念提取到一個新模型中,其他那些不要的概念就可以丟棄了,
(5) 頭腦風暴和實驗,語言和草圖,再加上頭腦風暴活動,將我們的討論變成“模型實驗室”,在這些討論中可以演示、嘗試和判斷上百種變化,當團隊走查場景時,口頭表達本身就可以作為所提議的模型的可行性測驗,因為人們聽到口頭表達后,就能立即分辨出它是表達得清楚、簡捷,還是表達得很笨拙,
正是頭腦風暴和大量實驗的創造力才使我們找到了一個富含知識的模型并對它進行提煉,在這個程序中,基于模型的語言提供了很大幫助,而且貫穿整個實作程序中的反饋倍訓也對模型起到了“訓練”作用,這種知識消化將團隊的知識轉化為有價值的模型,
知識消化
金融分析師要消化理解的內容是數字,他們篩選大量的詳細數字,對其進行組合和重組以便尋求潛在的意義,查找可以產生重要影響的簡單表示方式——一種可用作金融決策基礎的理解,
高效的領域建模人員是知識的消化者,他們在大量資訊中探尋有用的部分,他們不斷嘗試各種資訊組織方式,努力尋找對大量資訊有意義的簡單視圖,很多模型在嘗試后被放棄或改造,只有找到一組適用于所有細節的抽象概念后,作業才算成功,這一精華嚴謹地表示了所發現的最為相關的知識,
知識消化并非一項孤立的活動,它一般是在開發人員的領導下,由開發人員與領域專家組成的團隊來共同協作,他們共同收集資訊,并通過消化而將它組織為有用的形式,資訊的原始資料來自領域專家頭腦中的知識、現有系統的用戶,以及技術團隊以前在相關遺留系統或同領域的其他專案中積累的經驗,資訊的形式也多種多樣,有可能是為專案撰寫的檔案,有可能是業務中使用的檔案,也有可能來自大量的討論,早期版本或原型將經驗反饋給團隊,然后團隊對一些解釋做出修改,
在傳統的瀑布方法中,業務專家與分析員進行討論,分析員消化理解這些知識后,對其進行抽象并將結果傳遞給程式員,再由程式員撰寫軟體代碼,由于這種方法完全沒有反饋,因此總是失敗,分析員全權負責創建模型,但他們創建的模型只是基于業務專家的意見,他們既沒有向程式員學習的機會,也得不到早期軟體版本的經驗,知識只是朝一個方向流動,而且不會累積,
個人理解:現在依然有公司在這樣做,業務需求人員定義需求,再由架構師或者組長進行翻譯,之后直接分配給程式員任務,最后做出的程式往往和需求偏差較遠,大部分會議是組行和業務參加,真正實作功能的程式員沒有參與到會議討論中來,
有些專案使用了迭代程序,但由于沒有對知識進行抽象而無法建立起知識體系,開發人員聽專家們描述某項所需的特性,然后開始構建它,他們將結果展示給專家,并詢問接下來做什么,如果程式員愿意進行重構,則能夠保持軟體足夠整潔,以便繼續擴展它;但如果程式員對領域不感興趣,則他們只會了解程式應該執行的功能,而不去了解它背后的原理,雖然這樣也能開發出可用的軟體,但專案永遠也不會從原有特性中自然地擴展出強大的新特性,
好的程式員會自然而然地抽象并開發出一個可以完成更多作業的模型,但如果在建模時只是技術人員唱獨角戲,而沒有領域專家的協作,那么得到的概念將是很幼稚的,使用這些膚淺知識開發出來的軟體只能做基本作業,而無法充分反映出領域專家的思考方式,
在團隊所有成員一起消化理解模型的程序中,他們之間的互動也會發生變化,領域模型的不斷精化迫使開發人員學習重要的業務原理,而不是機械地進行功能開發,領域專家被迫提煉自己已知道的重要知識的程序往往也是完善其自身理解的程序,而且他們會漸漸理解軟體專案所必需的概念嚴謹性,
有這些因素都促使團隊成員成為更合格的知識消化者,他們對知識去粗取精,他們將模型重塑為更有用的形式,由于分析員和程式員將自己的知識輸入到了模型中,因此模型的組織更嚴密,抽象也更為整潔,從而為實作提供了更大支持,同時,由于領域專家也將他們的知識輸入到了模型中,因此模型反映了業務的深層次知識,而且真正的業務原則得以抽象,
模型在不斷改進的同時,也成為組織專案資訊流的工具,模型聚焦于需求分析,它與編程和設計緊密互動,它通過良性回圈加深團隊成員對領域的理解,使他們更透徹地理解模型,并對其進一步精化,模型永遠都不會是完美的,因為它是一個不斷演化完善的程序,模型對理解領域必須是切實可用的,它們必須非常精確,以便使應用程式易于實作和理解,
個人理解:對于業務和開發來說,最大的問題是思維想法的同步,同步最大的問題是交流溝通,程式員大部分相對內向沉默,業務有時候也會厭煩重復的表述,造成理解偏差,建立模型并共同改進精化可以很好的解決這個問題,既然開發人員的思維方式(機器思維)和業務人員的思維方式(功能結果導向思維)不同,那么就使用一個中間翻譯的語言,這個語言就叫做模型,也是抽象的模型,是大家一起來制定的一種抽象表達方式,每個人都要參與其中,并且不斷進行更新,模型也充當了業務轉化為開發邏輯的一種中間程序表示,
持續學習
當開始撰寫軟體時,其實我們所知甚少,專案知識零散地分散在很多人和檔案中,其中夾雜著其他一些無關資訊,因此我們甚至不知道哪些知識是真正需要的知識,看起來沒什么技術難度的領域很可能是一種錯覺——我們并沒意識到不知道的東西究竟有多少,這種無知往往會導致我們做出錯誤的假設,
同時,所有專案都會丟失知識,已經學到了一些知識的人可能干別的事去了,團隊可能由于重組而被拆散,這導致知識又重新分散開,被外包出去的關鍵子系統可能只交回了代碼,而不會將知識傳遞回來,而且當使用典型的設計方法時,代碼和檔案不會以一種有用的形式表示出這些來之不易的知識,因此一旦由于某種原因人們沒有口頭傳遞知識,那么知識就丟失了,
個人理解:團隊的解散,人員的離職或變更,檔案的丟失和散亂,都會使專案組丟失知識,有時候代碼寫完了但是沒有檔案或者注釋(程式員黑話:先開發產品功能,后寫檔案,其實就是懶得寫),別人接手需要經歷非常大的痛苦,然后瘋狂吐槽以前的開發人員,這些都可以歸于知識的丟失,
高效率的團隊需要有意識地積累知識,并持續學習,對于開發人員來說,這意味著既要完善技術知識,也要培養一般的領域建模技巧,但這也包括認真學習他們正在從事的特定領域的知識,那些善于自學的團隊成員會成為團隊的中堅力量,涉及最關鍵領域的開發任務要靠他們來攻克,這個核心團隊頭腦中積累的知識使他們成為更高效的知識消化者,
關鍵的模型元素被保留下來,早期作業啟動了知識消化的程序,這使得所有后續作業更加高效:團隊成員、開發人員和領域專家等都學到了知識,他們開始使用一種公共的語言,而且形成了貫穿整個實作程序的反饋倍訓,
個人理解:所有人都參與,制定模型,學習知識(業務邏輯或者開發思維或者處理流程等等都是知識),后期團隊效率會非常高,就算人員變更,只需要理解開發程序中一起制定的模型就可以了,
知識豐富的設計
當我們的建模不再局限于尋找物體和值物件時,我們才能充分吸取知識,因為業務規則之間可能會存在不一致,領域專家在反復研究所有規則、解決規則之間的矛盾以及以常識來彌補規則的不足等一系列作業中,往往不會意識到他們的思考程序有多么復雜,軟體是無法完成這一作業的,正是通過與軟體專家緊密協作來消化知識的程序才使得規則得以澄清和充實,并消除規則之間的矛盾以及洗掉一些無用規則,
個人理解:業務或者產品如果不懂開發,會提出一些天馬行空的功能,不會意識到他們的想法實作起來由多復雜,比如:產品經理要程式要開發一個功能,要求app根據手機殼的顏色而改變主題顏色(新聞有報道,產品經理被打了,哈哈哈),大家一起緊密協作來消化知識,可以消除這些矛盾或者無用的想法,
示例
我們從一個非常簡單的領域模型開始學習,基于此模型的應用程式用來預訂一艘船在一次航程中要運載的貨物

們規定這個應用程式的任務是將每件貨物(Cargo)與一次航程(Voyage)關聯起來,記錄并跟蹤這種關系,現在看來一切都還算簡單,應用程式代碼中可能會有一個像下面這樣的方法

由于總會有人在最后一刻取消訂單,因此航運業的一般做法是接受比其運載能力多一些的貨物,這稱為“超訂”,有時使用一個簡單的容量百分比來表示,如預訂110%的載貨量,有時則采用復雜的規則——主要客戶或特定種類的貨物優先,這是航運領域的一個基本策略,從事航運業的業務人員都知道它,但在軟體團隊中可能不是所有技術人員都知道這條規則,需求檔案中包含下面這句話:允許10%的超訂,(這個時候由問題了哈)


現在,一條重要的業務規則被隱藏在上面這段方法代碼內,非常容易誤解,我們主要考慮如何把這條規則更清楚地表達出來,并讓專案中的每個人都能了解到它,這將使我們得到一個類似的解決方案,
(1) 如果業務規則如上述代碼所寫,不可能有業務專家會通過閱讀這段代碼來檢驗規則,即使在開發人員的幫助下也無法完成,
(2) 非業務的技術人員很難將需求文本與代碼聯系起來,如果規則更復雜,情況將更糟,
修改成下面這樣:


現在所有人都清楚超訂是一個獨特的策略,而且超訂規則的實作即明確又獨立,
現在,我并不建議將這樣的精細設計應用到領域的每個細節中,第15章將深入闡述如何關注重點以及如何隔離其他問題或使這些問題最小化,這個例子的目的是說明領域模型和相應的設計可用來保護和共享知識,更明確的設計具有以下優點:
(1) 為了實作更明確的設計,程式員和其他各位相關人員都必須理解超訂的本質,明白它是一個明確且重要的業務規則,而不只是一個不起眼的計算,
(2) 程式員可以向業務專家展示技術工件,甚至是代碼,但應該是領域專家(在程式員指導下)可以理解的,以便形成反饋倍訓,
個人理解:模型要把重要的細節表達出來,不能隱藏的自己知道的認知中(就不告訴別人,說你這樣做就行了,這樣不好),要體現出為什么是這樣的,是什么導致必須要加入這個,要讓模型在成為溝通的橋梁時更加明確易懂,
深層模型
有用的模型很少停留在表面,隨著對領域和應用程式需求的理解逐步加深,我們往往會丟棄那些最初看起來很重要的表面元素,或者切換它們的角度,這時,一些開始時不可能發現的巧妙抽象就會漸漸浮出水面,而它們恰恰切中問題的要害,
前面的例子大體上是基于一個集裝箱航運專案,這是本書列舉的幾個專案之一,本書還有幾個示例會參考這個專案,本書所舉的示例都很簡單,即使不是航運專家也能理解它們,但在一個需要團隊成員持續學習的真實專案中,要想建立實用且清晰的模型則要求團隊成員既精通領域知識,也要精通建模技術,
在這個專案中,由于航運從預訂貨運開始,因此我們開發了一個能夠描述貨物和運貨航線等事物的模型,這是必要且有用的,但領域專家卻不買賬,他們有自己的考慮業務的方式,這種方式是我們沒有考慮到的,
最后,在經過幾個月的知識消化后,我們知道貨物的處理主要是由轉包商或公司中的操作人員完成的,這包括實際的裝貨、卸貨和運貨,航運專家的觀點是,各部分之間存在一系列的責任傳遞,法律責任和執行責任的傳遞由一個程序控制—從托運人傳遞到某個本地運輸商,再從這家運輸商傳遞到另一家運輸商,最后到達識訓人,通常,在一些重要的步驟中,貨物停放在倉庫里,在其他時間里,貨物則是通過復雜的物理步驟來運輸,而這些與航運公司的業務決策無關,在處理航線的物流之前,必須先確定諸如提單等法律檔案以及支付流程,
對航運業務有了更深刻的認識后,我們并沒有洗掉Itinerary(航線)物件,但模型發生了巨大改變,我們對航運業務的認識從“集裝箱在各個地點之間的運輸”轉變為“運貨責任在各個物體之間的傳遞”,處理這些責任傳遞的特性不再是一些附屬于裝貨作業的次要特性,而是由一個獨立的模型來提供支持,這個模型正是在理解了作業與責任之間的重要關系之后開發出來的,
知識消化是一種探索,它永無止境,
個人理解:隨著對業務的理解更加深刻以后,模型同時也要進行更新,會變得復雜,怎么辦?開發容易理解的一種形式是:就相當于sql中做子查詢,java開發中就小模塊封裝,大模塊呼叫函式,模型也是一樣,再做一個新模型,對某一部分功能做抽象,由大模型鏈接過去,例如:a-b-c原來是一個模型,后來增加到a-b-c-c1-c2-c3,c的功能原來越多,這個時候可以做成這樣:模型1是a-b-C,模型C(獨立小模型):c1-c2-c3,這就是深層模型的理解,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/1046.html
標籤:領域驅動設計
上一篇:運用領域模型
