本文既不推銷UML,也不推廣DDD,更不涉及各類論戰。-- 做者編程
某天又一次打開關於DDD(領域驅動設計)的PDF文檔時,本身有了個疑問:什麼是領域(Domain)?譯文中是這樣描述領域:銀行業務被銀行的內部人員和專家所熟知。他們知道全部的細節、全部的困難、全部可能 出現的問題、全部的業務規則。這些就是咱們永遠的起始點:領域。若是這就是領域,它彷佛不是"起始點",而是「所有」--所有的業務規則、所有的細節、所有可能出現的問題。個人疑問正是始於此:Domain映射到軟件,"所有"不就是整個系統?
架構
這裏有個概念漏洞,Domain是"所有",但不是全世界的"所有",那它是什麼的所有?顯然,譯文中看到的"銀行業務",其對應的Domain也不是指銀行業務系統的所有,所以Domain的概念相對清晰--一個有清晰邊界、內部的業務、規則、問題、細節都自成一派--你會問我,這是指對象(Object)吧!若是從低層次上講,二者是有關係的。下一個疑問:Domain和Object有什麼不一樣?異步
我思考的結果是封裝的級別不一樣:Object封裝的目標是調用其方法實現所承諾的功能,但系統中的對象是有依賴的;Domain封裝的目標是"所有"都在這裏,即不須要依賴其餘的Object或者Domain。之因此這麼想,主要的依據是從那個經常使用的例子:機場、航線、飛機,雖然我看的譯文中把這三個定義爲對象,使用UML畫了聚合關係;我更傾向於把它們當作Domain,即我認爲機場不會調用飛機的方法(或者人),二者只是相互關注了對方(的事件)。例如,飛機A1和機場B1經過無線電溝通(消息)。Object間的消息通常是帶着發送者或者接受者的數據,也就是A1發送的是B1要處理的;而Domain間的消息是否處理,如何處理則是徹底由接收者本身處理,發送者也不關心消息的處理。再一個疑問:如何達到"所有"封裝?分佈式
上面的例子中,我使用了"事件"這個關鍵字。事件(消息)不是新鮮事物,在面向對象的系統中,其做爲異構子系統、系統間異步調用的橋樑,起着重要的做用;因此我認爲「事件通知」不是實現Domain的途徑,由於它是同步調用的變種:消息的生產者和消費者仍然有業務邏輯上的自然聯繫。事件除了通知,還有一種模式是監聽。這種事件是公共資源,是開放的標準,不論採用廣播、總線、管道各類模式,Domain監聽本身關注的事件,並對其進行響應,若是產生了新的("開放")事件,則將事件發佈回(廣播、總線、管道的)'通道'。以機場和飛機爲例,機場廣播的跑道天氣信息,飛機的飛行員若是關心,則經過無線電接聽,若是不關心,則徹底能夠關閉無線電。spa
以上基本展現了我思考的過程。其間,我回顧了本身使用過的各類(X)O,(X)O包含面向服務(架構)-SO(A),面向方面(編程)-AO(P),面向對象-OO,面向過程-PO。設計
粗略地獲得了下圖:對象
從上圖中除了有關於Domain的思考,還想了關於如何更好的使用各類方法論。我有個觀點:同步就是兩次或者屢次異步交互的集成。接口
畫圖的過程當中,我又有了個疑問:服務間的異步通知類接口,是不是實現Domain的一種形態?經過與分佈式服務系統的拆分,我認爲:異步通知(接口)是一種補充,而不是Domain間交互的主要方式,它相似「塔臺呼叫711,711聽到請回答」;若是全程都是這樣飛行,塔臺須要爲每一個飛機配置一個導航員,且每一個飛機獨立使用一個頻率,這不是一個好設計,儘管它在航空管制初期多是可行的。事件
個人結論是:面向領域設計DDD中的領域是比對象、服務更加高度的封裝,領域包含本身的數據、行爲、控制等"所有",並對外部事件(或者消息)作出響應,按照本身的規則完成特定的功能。基於這樣的特色,Domain間的通信應該是異步事件監聽模式。在Domain內部,能夠利用面向對象、服務及各類方法論開發更耦合的功能--這能夠解釋爲何如今更多的系統是採用的同步調用方式運行。這也是另外一個層面的「外鬆內緊」的耦合。資源