昨天 Application Service 有用到一個叫做 MoneyTransfered
的 Domain Event。
Domain Event 很簡單,基本上就是把 Event new
出來,然後 Dispatch 出去,現在來看看昨天的 MoneyTransfered
, 它的實作其實很單純:
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MoneyTransfered
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $fromAccount;
public $toAccount;
public $timestamp;
public $amount;
public function __construct(array $attrs)
{
$this->fromAccount = $attrs['from'];
$this->toAccount = $attrs['to'];
$this->amount = $attrs['amount'];
$this->timestamp = $attrs['timestamp'];
}
}
剩下就是定義 Listener,再讓 Listener 呼叫 Application Service 做某些事。
現在整個專案是由多個 Bounded Context 所組成的,
因此我們必須定義清楚他們之間的關係,幫助我們更好的管理他們。
表達相依性的方式是用 U
(Upstream) 與 D
(Downstream) 來表達,其中 D
依賴於 U
。
有興趣更深入了解 Context Mapping 的朋友可以參考邦友 fx777 所寫的戰略設計:來聊聊 Bounded Context 的世間情 -- Context Mapping,圖文並茂相當好懂,我這邊只是從他的文章裡劃出重點而已。
管理相依的模式主要有這幾種:
兩個 Bounded Context 共用同一個模組,那兩者間的關係就屬於 Shared Kernel。
兩個 Bounded Context 需要共同協調制定開發計畫與專案管理,確保功能可以一起發布。
藉由 ACL 來建立一層隔離層,利用介面來將外部概念轉換成內部 Domain Model 能理解的概念。
上游定義介面,下游實現介面。但這要視情況而定,有的時候情況可能會反過來。
在系統中將幾個 Domain 的依賴完全切開,再由 UI 或其他方法進行整合。
通常用在要將系統重構成 DDD 模式時使用,先將原本系統定義為一個 Bounded Context,再配合 ACL 來與新建立的 Domain 溝通。
當 Bounded Context 間有單向的上下游關係時,上游方可以獨立於下游方完成開發,而下游方必須受限於上游方的開發計畫。與 Conformist 不同的是,Customer-Supplier 的關係裡上游方通常會顧及到下游方的需求。
Bounded Context 間有上下游關係時出現,但此時上游方沒有辦法滿足下游方的需求,這種關係我們就稱下游方為 Conformist。主要原因可能是系統的整合成本太高。
遇到這個情況時,可以考慮以下作法