分布式領域驅動設計
DDD領域驅動設計,應該就是一種系統設計的方法論,可以知道人們設計軟體。其實老外就喜歡總結一些方法論用于指導實踐,這一點還是很重要的。
DDD概述
DDD是一套關于軟體架構的指導原則。最重要的概念就是域模型。“域”是構成嘗試模組化的業務或領域的一組要求、限制和概念。我們可以了解成一個設計良好的OOP中的一個類,但在DDD中域更加注重描述業務領域。但OOP中的一個類主要是實踐上的事情,而域模型就是方法論了。比如它可以指導類該如何設計。
DDD的好處
DDD的目标是将較大的領域業務分解成更小、更易于管理的業務塊,然後就可以分别對這些小的業務塊模組化。簡單點來說DDD可以在業務的角度,指導如何對系統進行抽象。在軟體設計中,抽象、概括的能力非常重要,可以說是低級程式員和進階程式員的分水嶺。剛開始程式設計的時候,我覺得程式員就是用來實作業務的基本功能的,實作了就好了。随着後面技能的提升才發現,實作一個功能有很多種方法,但具體哪種才是一個最合适的方案呢?該如何選擇呢?這個時候就需要一個方法論來指導系統的設計了。
DDD元件
DDD提供了一組可以直接在代碼中使用的工具,它們将是應用程式的建構塊,這些建構塊組合起來可以建立更大的軟體系統。而這些建構塊會成為确定actor正确結構的完美候選對象。因為二者都是比較獨立的,高内聚低耦合!
域實體
DDD使用實體的概念來引用系統中可由鍵或複合鍵唯一标志的對象。也就是說一個實體必須有一個唯一鍵,鍵不同則代表不同的實體,鍵相同則代表相同的實體。這跟資料庫中含有主鍵的一行資料有點類似。實體可以包含可變的狀态且唯一可識别的标志,可以直接映射成一個actor。
域值對象
值對象在其包含的屬性之外沒有實體那樣的辨別,包含相同資料的兩個值對象則認為是相同的。值對象是不可變的,值對象的任意資料改變了,則變成了兩個不同的值對象。這跟scala中的case class有點相似。這跟actor之間傳遞的消息也一緻。用于在actor之間傳遞的消息被稱為消息協定。一個好的做法是将特定類型的actor消息嵌入到公共協定對象中。這個對象既可以是單個actor的伴生對象,也可以是單獨的協定對象。其實Akka用的多了,你就會發現,完全是在面向協定程式設計。因為case class越來越多,也越來越重要,甚至可能比actor還重要。
聚合與聚合根
聚合是應用程式内對象的集合。聚合建立了由系統中許多不同元素組成的邏輯分組,每個聚合都會被綁定到聚合根上。聚合根是聚合中的一個特殊實體,它負責管理該聚合中的其他成員。聚合的一個屬性是禁止其他聚合對聚合中的任何内容持有引用。是以如果想通路聚合中的一些元素,必須通過聚合根,不能直接通路。聚合根是系統的頂層部分,所有與系統的互動将以某種方式與聚合根進行對接。當然了聚合根的設計并不是死的,而是要根據實際的業務進行劃分,有時候還可能會改變。在Akka中,聚合根通常由父actor表示。
倉儲
倉儲是開始抽象出基礎架構問題的地方,他們可以在存儲問題的上層建立一個抽象層。倉儲的目的是從基礎架構問題中抽象出抽象層,使用倉儲的目标通常是從資料庫或其他存儲機制中重新建構聚合。當然在Akka中用一個actor來表示倉儲也是非常自然和合理的。
工廠和對象建立
工廠的主要作用是抽離出建立新的域對象時帶來的複雜性。工廠和倉儲的差別其實很小,工廠旨在抽象出新對象的建立,而倉儲旨在抽象時對現有對象的重新建立。這一點大概可以用設計模式中的工廠設計模式來了解。
域服務
服務是一個域對象,用來處理不适合作為聚合的操作,但服務可一個根據需要與聚合進行互動。在Akka中,服務可以是長期存在的actor,和其他聚合actor一起工作。或者可以是一個臨時建立的actor,任務完成後就會終止。其實臨時建立actor以完成某種任務,将會是一個非常适用的設計模式。
有界上下文
DDD中有很多基礎建構塊,而有界上下文應該就是使其組合到一起對外提供服務的界限。有界上下文表示彼此隔離的服務。比如“賬戶”這個域對象,在不同的有界上下文中是不一樣的,而有界上下文則是區分他們的一個方法、邊界、标準。将應用程式分成單獨的有界上下文并在多台機器上分發這些上下文的想法,其實就是分布式領域驅動設計(DDDD)的思想。