您好,登錄后才能下訂單哦!
本篇內容主要講解“php中的DDD有什么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“php中的DDD有什么用”吧!
DDD 是 Domain Driven Design 的縮寫,在中文中常被翻譯為領域驅動設計。在我們了解 DDD 是什么之前,首先討論下它不是什么。
DDD 不是一個軟件框架。但是基于 DDD 思想的框架是存在的,比如 Axon,它是以 DDD 為指導思想,使用 Java 實現的一個微服務軟件框架。
DDD 不是一種軟件設計模式。它不是像工廠,單例這樣子的設計模式。但是 DDD 思想中提出了諸如資源庫(Repository)之類的設計模式。
DDD 不是一種系統架構模式。它不是像 MVC 之類的架構模式。但是 DDD 思想中提出了諸如事件溯源(Event Souring),讀寫隔離(Command Query Responsibility Segregation) 之類的架構模式。
軟件是服務于人類,為提高人類生產效率而產生的一種工具, 每一個軟件都服務于某一個特定的領域。比如一個 CRM,它是以管理客戶數據為核心,幫助商戶與客戶保持聯系的工具。
而軟件的實質是計算機中運行的代碼,如何將抽象的代碼更準確地映射到人類所關心的領域中,這是軟件開發者一直在探尋的話題,不管是函數式編程(FP)還是面向對象編程(OOP)也好,都是為了幫助開發者開發出更貼近于領域中的軟件模型。
在傳統的軟件開發方法中,我們常常會遇到一系列影響軟件質量的技術以及非技術問題:
開發者熱衷于技術,但缺乏設計和業務思考。開發人員在不完全了解業務需求的情況下,閉門造車,即使功能上線也無人問津。
代碼輸入而非業務輸入。技術人員對技術實現情有獨鐘,出現殺雞焉用牛刀的情況。
過于重視數據庫。以數據庫設計為中心,而非業務來進行開發,結果往往是,軟件無法適應一直在變動的業務邏輯。
DDD 是一種設計思想,一種以領域(業務)為出發點,以解決軟件建模復雜度為目的設計思想,我們也可以將其理解為一種建模的方法論。
DDD 的設計思想分為戰略和戰術兩部分。
我們可以將戰略設計理解為宏觀層面的設計,它的目的包括,分析業務的復雜程度,拆分業務的領域范疇,指導業務整合方式等等 。我們可以將戰術設計理解為微觀層面(代碼層面)的設計,它為我們在實現業務邏輯提供一系列工具。
語言本是人類溝通的基本工具,然而開發人員習慣了使用技術術語,領域專家(領域專家在此泛指精通業務的專家,比如用戶,客戶等等)對技術術語毫不關心,于是造成了不可避免的溝通問題,一旦溝通出現問題,開發出來的軟件便很難解決領域專家的真正痛點。
通用語言是 DDD 思想的基石,它是開發人員和領域專家共同創建一套溝通語言,一套在團隊中流行的,通用的溝通語言,團隊的組員之間可使用通用語言進行無障礙交流。
這要求開發人員摒棄技術味濃重的技術術語,與領域專家合作,像領域專家一樣關注業務問題,共同挖掘并打磨業務中的術語,創建一套通用語言。
通用語言往往可以直接應用于代碼中,它可以直接被寫成一個類或者一個類的方法。
比如在開發一個購物車時,與其使用技術術語:
Cart::create(): 創建一個購物車。
Cart::updateStatus():更新購物車狀態。
Cart::remove():移除購物車。
我們不妨使用更貼近業務的通用語言:
Cart::init(): 創建一個購物車。
Cart::addItemToCart():添加商品。
Cart::removeItemFromCart():移除商品。
Cart::empty():清空購物車。
在使用后者時,開發人員不用解釋每一個類方法的意義,領域專家可以直接看懂每一個類方法的目的。開發人員甚至可以和領域專家坐在一起使用代碼來打磨業務流程。
在實現了通用語言自由以后,我們需要使用限界上下文來規定每一套通用語言的使用邊界。限界上下文是語義和語境的邊界,在其內的每一個元素都有自己特定的含義,也就是說每一個概念在一個限界上下文中都是獨一無二,不可以出現一詞多義的情況。
我們可以用一個簡單的例子來解釋限界上下文。比如在一個購物車的限界上下文中,我們可以用 User 一詞來代表購買商品的客戶。而在一個注冊系統中,我們可以用 User 一詞指的是帶有用戶名和密碼的賬號。雖然詞匯一樣,但是在不同的限界上下文中,它們的含義不同。
我們使用限界上下文和通用語言,對業務進行語言層面的拆分。限界上下文為領域中的每一個元素賦予清晰的概念,開發人員也就不會將情不自禁的在腦海中閃現多個支撐一個元素的概念,避免寫出“大泥球”(big ball of mud)代碼。
如果說限界上下文是對業務進行語言層面拆分的話,那么子域便是對業務進行商業價值的拆分。每一個商業都有自己的關注點,即便是看起來一樣的電商平臺,淘寶是開放平臺模式,京東是價值鏈整合模式,一個明顯的區別是,淘寶使用第三方物流而京東自建物流體系。
那么作為一個開發人員,為何要關心看起來似乎與自己無關的商業模式呢?恰恰相反,只有當我們了解一個商業的結構時,才能開發出一個主次分明的系統來支撐一個商業的飛速發展。
子域便是這樣一個幫助我們劃分主次的工具。
有三種類型的子域:
核心域(Core Domain):這是系統中需要最大投資的領域,它代表著整個商業的核心競爭力。我們需要花大量資源以及資源來打磨核心域,這關乎一個企業的存亡。比如京東的自建物流系統。
支撐域(Supporting Domain):此領域并非一個企業的核心業務,但是核心域卻離不開它,它可以采用外包定制方案實現。比如認證上下文,權限上下文。
通用域(Generic Domain):如果已有成熟的解決方案,通用域可以采購現成方案來,如果沒有,也可以采用外包,在通用域上的投資應該是最小的。比如對于淘寶而言,物流便是其通用域。
限界上下文和子域的關系眾說紛紜,有專家提倡1:1,也有專家提倡1:N。個人比較提倡 1:1, 由于受實現領域驅動設計一書作者影響比較深。
在一個龐大的系統中,限界上下文之間必定存在一定的依賴關系。如何將一個上下文中的概念映射到另一個上下文中?我們使用上下文映射。
以下是幾種上下文映射的關系類型:
合作關系(Partnership)
共享內核(Shared Kernel)
客戶方-供應方開發(Customer-Supplier Development)
遵奉者(Conformist)
防腐層(Anticorruption Layer)
開放主機服務(Open Host Service)
發布語言(Published Language)
另謀他路(SeparateWay)
大泥球(Big Ball of Mud)
以上都是比較抽象的概念,有時兩個限界上下文之間也可以存在多重關系。
以上便是 DDD 戰略設計的幾個核心概念。
如何為限界上下文中的概念建立模型,我們將使用的是 DDD 所提供的戰術設計。
首先我們講到的是,實體。
實體是領域中獨立事物的模型,每個實體都擁有一個唯一的標識符,比如 ID, UUID,Username 等等。大多數情況下,實體是可變的,它的狀態會隨著時間的遷移改變,不過,一個實體不一定必須可變。
實體的最大的特征是它的個體性,唯一性。比如在一個簡單的購物車上下文中,訂單(Order) 便是一個實體,ID 是它的標識符,它的狀態可以在提交(placed),確認(confirmed) 以及已退 (refunded) 之間變化。
值對象是領域中用來描述,量化或者測量實體的模型。和實體不同,值對象沒有唯一的標識符,兩個對等的值對象是可以替換的。值對象具有不變性(Immutability),一旦創建以后,一個值對象的屬性就定型了,不可更改。
理解值對象的最直接的方法是,想象我們現實生活中的鈔票,在日常生活中,甲的十塊錢人民幣和乙的十塊錢人民幣是可以對等交換的。
在上文的購物車上下文中,金額(Money)便是一個值對象,金額由貨幣(currency)和數目(amount):
class Money { public $currency; public $amount; function __construct($currency, $amount) { $this->currency = $currency; $this->amount = $amount; } }
使用值對象進行建模,能幫助我們用代碼更精確地建立領域模型。
聚合是什么?聚合是上下文中對業務領域更精細的劃分,每一個聚合保證自己的業務一致性。
那么什么是業務不變性?業務不變性表示一個業務規則,該規則在業務領域中不可違背,必須保證其一致性。比如,在進行訂單退款時,退款金額不可以超過已付金額。
聚合的組成部分是實體和值對象,有時候也只有實體。為了保護聚合的業務一致性,每個聚合只可以通過某一個實體對其進行操作,該實體被稱為聚合根。
領域事件是通過通用語言分析出來的事件,與常見的事務事件不同的是它與業務息息相關,所以它的命名往往夾帶業務名詞,而不應該與數據庫掛鉤。比如購物車增添商品,對應的領域事件應該是 ProductAddedToCart, 而不是 CartUpdated。
DDD 還提供了諸如應用服務(Application Service),領域服務(Domain Service) 等戰術設計,DDD 還提出了文章開頭就提過的事件溯源,六邊形等架構模式,在此我們將不一一介紹。
DDD 的核心是從業務的角度為軟件建立模型,其目的是打造更貼近業務的代碼,能更直觀的從代碼理清業務流程。 然而實現 DDD 并非一日之舉,它需要不斷的實踐,不斷的打磨。
到此,相信大家對“php中的DDD有什么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。