非原創,感謝《領域驅動設計》這本書數據庫
領域模型可成爲軟件項目通用語言的核心。該模型是一組得自於項目人員頭腦中的概念,以及反映了領域深層含義的術語和關係。這些術語和相互關係提供了模型語言的語義,雖然語言是爲領域量身定製的,但就技術開發而言,其依然足夠精確。正是這條相當重要的紐帶,將模型與開發活動結合在一塊兒,並使模型與代碼緊密綁定。這種基於模型的交流並不侷限於UML(統一建模語言)圖。爲了最有效地使用模型,須要充分利用各類交流手段。基於模型的交流提升了書面文檔的效用,也提升了敏捷過程當中再度強調的非正式圖表和交談的效用。它還經過代碼自己及對應的測試促進了交流。編程
雖然領域專家對軟件開發的技術術語所知有限,但他們能熟練使用本身領域的術語——可能還具備各類不一樣的風格。另外一方面,開發人員可能會用一些描述性的、功能性的術語來理解和討論系統,而這些術語並不具有領域專家的語言所要傳達的意思。或者,開發人員可能會建立一些用於支持設計的抽象,但領域專家沒法理解這些抽象。負責處理問題不一樣部分的開發人員可能會開發出各自不一樣的設計概念以及描述領域的方式.編程語言
因爲語言上存在鴻溝,領域專家們只能模糊地描述他們想要的東西。開發人員雖然努力去理解一個本身不熟悉的領域,但也只能造成模糊的認識。雖然少數團隊成員會設法掌握這兩種語言,但他們會變成信息流的瓶頸,而且他們的翻譯也不許確。(溝通很是重要)工具
在一個沒有公共語言的項目上,開發人員不得不爲領域專家作翻譯。而領域專家須要充當開發人員與其餘領域專家之間的翻譯。甚至開發人員之間還須要互相翻譯。這些翻譯使模型概念變得混淆,而這會致使有害的代碼重構。這種間接的溝通掩蓋了分裂的造成——不一樣的團隊成員使用不一樣的術語而尚不自知。因爲軟件的各個部分不可以渾然一體,所以這就致使沒法開發出可靠的軟件。翻譯工做致使各種促進深刻理解模型的知識和想法沒法結合到一塊兒。學習
平常討論所使用的術語與代碼(軟件項目的最重要產品)中使用的術語不一致。甚至同一我的在講話和寫東西時使用的語言也不一致,這致使的後果是,對領域的深入表述經常稍縱即逝,根本沒法記錄到代碼或文檔中。翻譯使得溝通不順暢,並削弱了知識消化。測試
然而任何一方的語言都不能成爲公共語言,由於它們沒法知足全部的需求。全部翻譯的開銷,連帶着誤解的風險,成本實在過高了。項目須要一種公共語言,這種語言要比全部語言的最小公分母健壯得多。經過團隊的一致努力,領域模型能夠成爲這種公共語言的核心,同時將團隊溝通與軟件實現緊密聯繫到一塊兒。該語言將存在於團隊工做中的方方面面。ui
我的理解:上面說法太絕對了,主要是爲了突出通用語言的重要性。沒必要在乎。編碼
UBIQUITOUS LANGUAGE(通用語言)的詞彙包括類和主要操做的名稱。語言中的術語,有些用來討論模型中已經明確的規則,還有一些則來自施加於模型上的高級組織原則。最後,團隊經常應用於領域模型的模式名稱也使這種語言更爲豐富。翻譯
開發人員應該使用基於模型的語言來描述系統中的工件、任務和功能。這個模型應該爲開發人員和領域專家提供一種用於相互交流的語言,並且領域專家還應該使用這種語言來討論需求、開發計劃和特性。語言使用得越廣泛,理解進行得就越順暢。設計
至少,咱們應該將它做爲目標。但最初,模型可能不太好,所以沒法很好地履行這些職責。它可能不會像領域的專業術語那樣具備豐富的語義。但咱們又不能直接使用那些術語,由於它們有歧義和矛盾。模型可能缺少開發人員在代碼中所建立的更爲微妙和靈活的特性,這要麼是由於開發人員認爲模型沒必要具有這些特性,要麼是由於編碼風格是過程式的,只能隱含地表達領域概念。
儘管模型和基於模型的語言之間的次序像是循環論證,可是,可以產生更有用模型的知識消化過程依賴於團隊投身於基於模型的語言。持續使用UBIQUITOUS LANGUAGE能夠暴露模型中存在的缺點,這樣團隊就能夠嘗試並替換不恰當的術語或組合。當在語言中發現缺失時,新的詞語將被引入到討論中。這些語言上的更改也會在領域模型中引發相應的更改,並促使團隊更新類圖並重命名代碼中的類和方法,當術語的意義改變時,甚至會致使行爲也發生改變。
我的理解:儘管模型難以很快的理解,有可能一個團隊用了好久才達成共識造成一套本身理解的模型,可是對於剛剛加入的人來講就像天書,無疑增長的學習成本,若是模型更新過程當中,有些術語發生變動(隨着理解的深刻),會致使功能重作。
將模型做爲語言的支柱。確保團隊在內部的全部交流中以及代碼中堅持使用這種語言。在畫圖、寫東西,特別是講話時也要使用這種語言。經過嘗試不一樣的表示方法(它們反映了備選模型)來消除難點。而後重構代碼,從新命名類、方法和模塊,以便與新模型保持一致。解決交談中的術語混淆問題,就像咱們對普通詞彙造成一致的理解同樣。要認識到,UBIQUITOUS LANGUAGE的更改就是對模型的更改。領域專家應該抵制不合適或沒法充分表達領域理解的術語或結構,開發人員應該密切關注那些將會妨礙設計的有歧義和不一致的地方。有了UBIQUITOUS LANGUAGE,模型就不只僅是一個設計工件了。它成爲開發人員和領域專家共同完成的每項工做中不可或缺的部分。語言以動態形式傳遞知識。使用這種語言進行討論可以呈現圖和代碼背後的真實含義。
假如將交談從溝通方式中除去的話,那會是巨大的損失,由於人類自己頗具談話的天賦。遺憾的是,當人們交談時,一般並不使用領域模型的語言。
可能開始時你並不認爲上述論斷是正確的,並且的確有例外狀況。但下次你參加需求或設計討論時,不妨認真聽一下。你將聽到人們用業務術語或者各類業餘術語來描述功能。還會聽到人們討論技術工件和具體的功能。固然,你還會聽到來自領域模型的術語;在人們共同使用的那部分業務術語中,那些顯而易見的名詞在編碼時一般被用做對象名稱,所以這些術語常常被人們說起。但你是否也聽到一些使用當前領域模型中的關係和交互來描述的措辭呢?
改善模型的最佳方式之一就是經過對話來研究,試着大聲說出可能的模型變化中的各類結構。這樣不完善的地方很容易被聽出來。
例如:「若是咱們向Routing Service提供出發地、目的地和到達時間,就能夠查詢貨物的停靠地點,嗯……將它們存到數據庫中。」(含糊且偏重於技術);「出發地、目的地……把它們都輸入到Routing Service中,然後咱們獲得一個Itinerary,它包含咱們所需的所有信息。」(更具體,但過於囉嗦);「Routing Service查找知足Route Specification的Itinerary。」(簡潔)
我的理解:簡潔、抽象、完整的表達,就是模型的描述語言。儘可能不說白話,相似文言文。若是剛開始使用模型語言不習慣,也要在溝通時候去適應,大膽說出來,一塊兒適應,造成習慣。
討論系統時要結合模型。使用模型元素及其交互來大聲描述場景,而且按照模型容許的方式將各類概念結合到一塊兒。找到更簡單的表達方式來說出你要講的話,而後將這些新的想法應用到圖和代碼中。
技術人員一般認爲業務專家最好不要接觸領域模型,他們認爲:
「領域模型對他們來講太抽象了。」
「他們不理解對象。」
「這樣咱們就不得不用他們的術語來收集需求。」
固然,設計中有一些技術組件與領域專家無關,但模型的核心最好讓他們參與。過於抽象?那你怎麼知道抽象是否合理?你是否像他們同樣深刻理解領域?有時,某些特定需求是從底層用戶那裏收集的,他們在描述這些需求時可能會用到一小部分更具體的術語,但領域專家應該可以更深刻地思考他們所從事的領域。若是連經驗豐富的領域專家都不能理解模型,那麼模型必定出了什麼問題。
最初,當用戶討論系統還沒有建模的將來功能時,他們沒有模型可供使用。但當他們開始與開發人員一塊兒仔細討論這些新想法時,探索共享模型的過程就開始了。最初的模型可能很笨拙且不完整,但會逐漸精化。隨着新語言的演進,領域專家必須付出更多努力來適應它,並更新那些仍然很重要的舊文檔。當領域專家使用這種語言互相討論,或者與開發人員進行討論時,很快就會發現模型中哪些地方不符合他們的須要,甚至是錯誤的。另外一方面,模型語言的精確性也會促使領域專家(在開發人員的幫助下)發現他們想法中的矛盾和含糊之處。
我的理解:不要擔憂業務領域專家聽不懂技術設計的模型語言,你們能夠一塊兒來討論,共同探索,業務人員也要主動去適應,一旦理解後,能夠提出本身的意見,幫助改進模型。總的來講,使用模型就是好,有困難-克服。
開發人員和領域專家能夠經過一步一步地使用模型對象來走查場景,從而對模型進行非正式的測試。每次討論都是開發人員和專家一塊兒使用模型的機會,在這個過程當中,他們能夠加深彼此的理解,並對概念進行精化。領域專家可使用模型語言來編寫用例,甚至能夠直接利用模型來具體說明驗收測試。
開發人員的確會使用領域專家沒法理解的技術術語。開發人員有其所需的大量術語來討論系統技術。幾乎能夠確定的是,用戶也會用開發人員沒法理解的、超出應用程序範疇的專用術語。這些都是對語言的擴展。但在這些語言擴展中,同一領域的相同詞彙不該該反映不一樣的模型。有了UBIQUITOUS LANGUAGE以後,開發人員之間的對話、領域專家之間的討論以及代碼自己所表達的內容都基於同一種語言,都來自於一個共享的領域模型。
每當我參加討論軟件設計的會議時,若是不在白板或畫板上畫圖,我就很難討論下去。我畫的大部分是UML圖,主要以類圖和對象交互圖爲主。
有些人天生是視覺動物,圖能夠幫助人們掌握某些類型的信息。UML圖在傳達對象之間的關係上真是遊刃有餘,並且也很擅長表現交互。但它們卻沒法給出這些對象的概念定義。在會議中,我會一邊畫圖一邊用語言來豐富它們的意義,或者在與其餘參與者討論時進行解釋。簡單、非正式的UML圖可以維繫整個討論。繪製一幅包含當前問題最關鍵的3~5個對象的圖,這樣每一個人均可以集中注意力。全部人就對象關係會達成一致的認識,更重要的是,他們將使用相同的對象名稱。如此,口頭討論會更加高效。當人們嘗試不一樣的想法時,圖也隨之改變,草圖在某種程度上能夠反映討論的變化,這是討論中真正重要的部分。畢竟,UML就是統一建模語言。
當人們必須經過UML圖表示整個模型或設計時,麻煩也隨之而來。不少對象模型圖在某些方面過於細緻,同時在某些方面又有不少遺漏。說它們過於細緻是由於人們認爲必須將全部要編碼的對象都放到建模工具中。而細節過多的結果是「只見樹木,不見森林」。
我的理解:我認爲uml也能夠說是模型的一種表達形式,隨便在白板上劃也是一種模型,只不過不那麼規範,比較隨意
UML也不是一種十分使人滿意的編程語言。我從未見過有人使用建模工具的代碼生成功能達到了預期目的。若是UML的能力沒法知足須要,一般人們就不得不忽略模型最關鍵的部分,由於有些規則並不適合用線框圖來表示。固然,代碼生成器也沒法使用上面所說的那些文本註釋。若是確實能使用UML這樣的繪圖語言來編寫可執行程序,那麼UML圖就會退化爲程序自己的另外一種視圖,這樣,「模型」的真正含義就丟失了。若是使用UML做爲實現語言,則仍然須要利用其餘手段來表達模型的確切含義。
圖是一種溝通和解釋手段,它們能夠促進頭腦風暴。簡潔的小圖可以很好地實現這些目標,而涵蓋整個對象模型的綜合性大圖反而失去了溝通或解釋能力,由於它們將讀者淹沒在大量細節之中,加之這些圖也缺少目的性。鑑於此,咱們應避免使用一應俱全的對象模型圖,甚至不能使用包含全部細節的UML數據存儲庫。相反,應使用簡化的圖,圖中只包含對象模型的重要概念——這些部分對於理解設計相當重要。本書中的圖都是我在項目中使用過比較典型的圖。它們很簡單,並且具備很強的解釋能力,在澄清一些要點時,還使用了一些非標準的符號。它們顯示了設計約束,但它們不是面面俱到的設計規範。它們只體現了思想綱要。
設計的重要細節應該在代碼中體現出來。良好的實現應該是透明的,清楚地展現其背後的模型。互爲補充的圖和文檔可以引導人們將注意力放在覈心要點上。天然語言的討論能夠填補含義上的細微差異。這就是爲何我喜歡把典型的UML使用方法顛倒過來的緣由。一般的用法是以圖爲主,輔以文本註釋;而我更願意以文本爲主,用精心挑選的簡化圖做爲說明。
模型不是圖。圖的目的是幫助表達和解釋模型。代碼能夠充當設計細節的存儲庫。書寫良好的Java代碼與UML具備一樣的表達能力。通過仔細選擇和構造的圖能夠幫助人們集中注意力,並起到指導做用,固然前提條件是不能強制用圖來表示所有模型或設計,由於這樣會削弱圖的清晰表達的能力。
口頭交流能夠解釋代碼的含義,所以可做爲代碼精確性和細節的補充。雖然交談對於將人們與模型聯繫起來是相當重要的,但書面文檔也是必不可少的,任何規模的團隊都須要它來提供穩定和共享的交流。但要想編寫出可以幫助團隊開發出好軟件的書面文檔倒是一個不小的挑戰。
一句話:好記性不如爛筆頭。文檔應做爲代碼和口頭交流的補充
每種敏捷過程在編寫文檔方面都有本身的理念。極限編程主張徹底不使用(多餘的)設計文檔,而讓代碼解釋本身。實際運行的代碼不會說謊,而其餘文檔則否則。運行代碼所產生的行爲是明確的。
極限編程就是敏捷開發,敏捷開發不提倡寫太多文檔,能省就省,代碼多些註釋,代替文檔。
極限編程只關注對程序及可執行測試起做用的因素。因爲爲代碼添加的註釋並不影響程序的行爲,所以它們每每沒法與當前代碼及其模型保持同步。外部文檔和圖也不會影響程序的行爲,所以它們也沒法保持同步。另外一方面,口頭交流和臨時在白板上畫的圖不會長久保留而產生混淆。依賴代碼做爲交流媒介能夠促使開發人員保持代碼的整潔和透明。
將代碼做爲設計文檔也有侷限性。它可能會把讀代碼的人淹沒在細節中。儘管代碼的行爲是很是明確的,但這並不意味着其行爲是顯而易見的。就算技術人員能夠看懂代碼,專業領域的業務人員怎麼辦???因此,文檔仍是有必要的,實事求是來制定開發方式和文檔編寫方式。
文檔應當鮮活並保持最新。設計文檔的最大價值在於解釋模型的概念,幫助在代碼的細節中指引方向,或許還能夠幫助人們深刻了解模型預期的使用風格。根據不一樣的團隊理念,整個設計文檔可能會十分簡單,如只是貼在牆上的一組草圖,也可能會很是詳盡。
良好的代碼具備很強的表達能力,但它所傳遞的信息不能確保是準確的。一段代碼所產生的實際行爲是不會改變的。可是,方法名稱可能會有歧義、會產生誤導或者由於已通過時而沒法表示方法的本質含義。變量和代碼組織方式所表達出來的意思未必嚴格。好的編程風格會盡力使這種聯繫直接化,但其仍然主要靠開發人員的自律。編碼時須要一絲不苟的態度,只有這樣才能編寫出「言行所有正確」的代碼。
在實現、設計和團隊交流中使用同一個模型做爲基礎。若是各有各的模型,將會形成危害。
模型在幫助領域學習方面也具備很大價值。對設計起到推進做用的模型是領域的一個視圖,但爲了學習領域,還能夠引入其餘視圖,這些視圖只用做傳遞通常領域知識的教學工具。出於此目的,人們可使用與軟件設計無關的其餘種類模型的圖片或文字。
驅動軟件開發過程的技術模型必須通過嚴格的精簡,以便用最小化的模型來實現其功能。而解釋性模型則能夠包含那些提供上下文的領域方面——這些上下文用於澄清範圍更窄的模型。
解釋性模型提供了必定的自由度,能夠專門爲某個特殊主題定製一些表達力更強的風格。領域專家在一個領域中所使用的視覺隱喻一般呈現了更清晰的解釋,這能夠教給開發人員領域知識,同時使領域專家們的意見更一致。解釋性模型還能夠以一種不一樣的方式來呈現領域,而且各類不一樣角度的解釋有助於人們更好地學習。
解釋性模型沒必要是對象模型,並且最好不是。實際上在這些模型中不使用UML是有好處的,這樣能夠避免人們錯誤地認爲這些模型與軟件設計是一致的。儘管解釋性模型與驅動設計的模型每每有對應關係,但它們並不徹底相似。爲了不混淆,每一個人都必須知道它們之間的區別。
例如:
考慮一個用來追蹤航運公司貨物的應用程序。模型包含一個詳細的視圖,它顯示瞭如何將港口裝卸和貨輪航次組合爲一次貨運的操做計劃:
但對外行而言,類圖可能起不到多大的說明做用。
在這種狀況下,解釋性模型能夠幫助團隊成員理解類圖的實際含義。圖2-5是表示相同概念的另外一種方式。
圖中的每根線段都表示貨物的一種狀態——或者正在港口裝卸(裝貨或卸貨),或者停放在倉庫裏,或者正在運輸途中。這個圖並無與類圖中的細節一一對應,但強調了領域的要點。這種圖連同對它所表示的模型的天然語言解釋,可以幫助開發人員和領域專家理解更嚴格的軟件模型圖。綜合使用這兩種圖要比單獨使用一種圖更容易理解。