當前位置: 華文世界 > 科技

DDD - 領域模型

2024-03-21科技

本書為作出設計決策提供了一個框架,並且為討論領域設計提供了一個技術詞匯庫

領域驅動設計是一種思維方式,也是一組優先任務,它旨在加速那些必須處理復雜領域的軟體計畫的開發

模型

  • 模型被用來描繪人們所關註的現實或想法的某個方面,是一種簡化。
  • 它是對現實的解釋:把與解決問題密切相關的方面抽象出來,而忽略無關的細節
  • 模型這種知識形式對知識進行了選擇性的簡化和有意的結構化。適當的模型可以使人理解資訊的意義,並專註於問題
  • 領域模型

    領域模型並非某種特殊的圖,而是這種圖所要傳達的思想。它絕不單單是領域專家頭腦中的知識,而是對這類知識嚴格地組織且有選擇地抽象。圖可以表示和傳達一種模型,同樣精心書寫的程式碼或文字也能達到同樣的目的。

    領域建模並不是盡可能建立一個符合「現實」的模型。即使是對具體、真實世界中的事物進行建模,所得到的模型也不過是對事物的一種模擬。它也不單單是為了實作某種目的而構造出來的軟體機制。建模更像是制作電影--出於某種目的而概況地反映現實。例如:即使是一部紀錄片也不會原封不動地展示真實生活。就如同電影制片人講述故事或闡明觀點時,他們會選擇素材,並以一種特殊方式將他們呈現給觀眾。

    模型在DDD中的作用

  • 模型和設計的核心互相影響
    模型與實作之間的緊密聯系才能使模型變得有用,並確保我們在模型中所進行的分析能夠轉化為最終產品
  • 模型是團隊所有成員使用的通用語言的中樞
    由於模型與實作之間的關聯,開發人員可以使用該語言來討論程式,也可以在無需轉譯的情況下與領域專家進行溝通
  • 模型是濃縮的知識
    模型是團隊一致認同的領域知識的組織方式和重要元素的區分方式。透過我們如何選擇術語,分解概念以及將概念聯系起來,模型記錄了我們看待領域的方式。
  • 軟體的核心

    軟體的核心是其為使用者解決領域相關的問題的能力。

    當領域很復雜時,這是一項艱巨的任務,它要求高水平技術人員的共同努力。開發人員必須鉆研領域以獲取業務知識,他們必須磨礪其建模技巧,並精通領域設計。

    Ubiquitous Language(通用語言)

    想要建立一種靈活的、蘊含豐富知識的設計,需要一種通用的、共享的團隊語言,以及對語言不斷地試驗。

    語言鴻溝

    領域專家對軟體開發的技術術語所知有限,但他們能熟練使用自己領域的術語;開發人員可能會用一些描述性的、功能性的術語來理解和討論系統,而這些術語並不具備領域專家的語言所要表達的意思。由於雙方語言上存在鴻溝,領域專家只能模糊地描述他們想要的東西;開發人員雖然努力去理解一個自己不熟悉的領域,但也只能形成模糊的認識。

    如果語言支離破碎,計畫必將遭遇嚴重的問題。
    1、領域專家使用他們自己的術語,而技術團隊所使用的語言則經過調整,以便從設計角度討論領域。 2、日常討論所使用的術語與程式碼中使用的術語不一致,甚至同一個人在講話和寫東西時使用的語言也不一致,這將導致對領域的深刻表述常常稍縱即逝,根本無法記錄到程式碼或文件中
    3、轉譯使得溝通不暢,並削弱了知識消化
    4、任何一方的語言都不能成為公共語言,因為它們無法滿足所有的需求

    UBIQUITOUS LANGUAGE

    計畫需要一種公共語言,這種語言要比所有語言的最小公分母健壯。領域模型可以成為這種公共語言的核心,同時將團隊溝通與軟體實作緊密聯系到一起。該語言將存在於團隊工作中的方方面面。

    UBIQUITOUS LANGUAGE的詞匯包括類和主要操作的名稱。語言中的術語有些用來討論模型中已經明確的規則;有些則來自施加於模型上的高級組織原則(Bounded Contex、Core Domain、Generic Subdomain);有些常常套用於領域模型的模式名稱。

    模型之間的關系成為所有語言都具有的組合規則。詞和短語的意義反映了模型的語意。

    開發人員應該使用基於模型的語言來描述系統中的工作、任務和功能。這個模型應該為開發人員和領域專家提供一種用於互相交流的語言,而且領域專家還應該使用這種語言來討論需求、開發計劃和特性。語言使用得越普通,理解進行得就越順暢。

    討論系統時要結合模型。使用模型元素及其互動來大聲描述場景,並且按照模型允許的方式將各種概念結合到一起。找到更簡單的表達方式來講出你要講的話,然後將這些新的想法套用到圖和程式碼中。

    「如果我們向Routing Service提供出發地、目的地和到達時間,就可以查詢貨物的停靠地點,......將它們存到資料庫中。」(含糊且偏重於技術)

    「出發地、目的地......把它們都輸入到Routing Service中,而後我們得到一個Itinerary,它包含我們所需的全部資訊。」(更具體,但過於啰嗦)

    Routing Service尋找滿足Route Specification的Itinerary。(簡潔)

    Model-Driven Design(模型驅動設計)

    許多復雜計畫確實在嘗試使用某種形式的領域模型,但是並沒有把程式碼的編寫與模型緊密聯系起來。這些計畫所設計的模型在計畫初期可能用來做一些探索工作。這種模型完全脫離程式設計,是由不同的人員開發;它是對業務領域進行分析的結果,它在組織業務領域中的概念時,完全不去考慮在軟體系統中將會起到的作用,這種模型被稱之為分析模型。

    分析模型僅僅是理解工具,在建立分析模型時並沒有考慮程式設計的問題,因此分析模型很有可能無法滿足程式設計的需求。如果開發人員不得不重新對設計進行抽象,那麽大部份的領域知識就會被丟棄。如果整個程式設計或者其核心部份沒有與領域模型相對應,那麽這個模型就是沒有價值的,軟體的正確性也值得懷疑。

    Model-Driven Design不再將分析模型和程式設計分離開,而是尋求一種能夠滿足這兩方面需求的單一模型。模型和設計的繫結需要的是在分析和程式設計階段都能發揮良好作用的模型。如果模型對於程式的實作來說顯得不太實用時,我們必須重新設計它。而如果模型無法忠實地描述領域的關鍵概念,也必須重新設計它。

    Hands-On Modeler(親身實踐的建模者)

    管理層認為建模人員就應該只負責建模工作,編寫程式碼是在浪費這種技能。開始計畫進展得還算順利,領域專家以及各團隊的開發負責人共同工作,消化領域知識並提煉出一個不錯的核心模型。但該模型卻從來沒有派上用場,原因有兩個:

    其一:模型的一些意圖在其傳遞過程中遺失了。模型的整體效果受細節影響很大,這些細節問題並不是總能在UML圖或者一般討論中遇到的

    其二:模型與程式設計實作及技術互相影響,而模型設計者無法直接獲得這種反饋。

    如果編寫程式碼的人員認為自己沒必要對模型負責,或者不知道如何讓模型為應用程式服務,那麽這個模型就和程式沒有任何關聯。如果開發人員沒有意識到改變程式碼就意味著改變模型,那麽他們對程式的重構不但不會增強模型的作用,反而還會削弱它的效果。同樣,如果建模人員不參與到程式實作的過程中,那麽對程式實作的約束就沒有切身的感受,即使有,也會很快忘記。

    Model-Driven Design的兩個基本要素(即模型要支持有效的實作並抽象出關鍵的領域知識)已經失去了一個,最終模型將變得不再實用。

    如果分工阻斷了設計人員與開發人員之間的協作,使他們無法傳達實作Model-Driven Design的種種細節,那麽經驗豐富的設計人員則不能將自己的知識和技術傳遞給開發人員

    Hands-On Modeler並不意味著團隊成員不能有自己的專業角色。任何參與建模的技術人員,不管在計畫中的主要職責是什麽,都必須花時間了解程式碼。任何負責修改程式碼的人員則必須學會用程式碼來表達模型。每一個開發人員都必須不同程度地參與模型討論並且與領域專家保持聯系。參與不同工作的人都必須有意識地透過Ubiquitous Language與接觸程式碼的人及時交換關於模型的想法。