非原創,感謝《領域驅動設計》這本書java
(1) 模型和實現的綁定。最初的原型雖然簡陋,但它在模型與實現之間創建了早期連接,並且在全部後續的迭代中咱們一直在維護該連接。程序員
(2) 創建了一種基於模型的語言。隨着項目的進展,雙方都可以直接使用模型中的術語,並將它們組織爲符合模型結構的語句,並且無需翻譯便可理解互相要表達的意思。sql
我的理解:定義專業詞語的字典解釋,保證每一個人對每一個術語的理解都是同樣的編程
(3) 開發一個蘊含豐富知識的模型。對象具備行爲和強制性規則。模型並不只僅是一種數據模式,它仍是解決複雜問題不可或缺的部分。模型包含各類類型的知識。架構
(4) 提煉模型。在模型日趨完整的過程當中,重要的概念不斷被添加到模型中,但一樣重要的是,再也不使用的或不重要的概念則從模型中被移除。當一個不須要的概念與一個須要的概念有關聯時,則把重要的概念提取到一個新模型中,其餘那些不要的概念就能夠丟棄了。app
(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。這就是深層模型的理解。