複製
這是一個公平的一點是,當命令和事件序列化,編譯時安全性丟失,但在一個靜態類型語言,我還是更喜歡強類型的命令和事件類型。
原因是它給了你一個負責解釋消息元素的代碼庫。序列化往往是相當(類型)安全的;反序列化是您可能遇到問題的地方。
不過,我寧願在一個地方處理任何這樣的問題,而不是分散在整個代碼庫中。
這對事件特別重要,因爲您可能有多個事件處理程序處理相同類型的事件。如果您將事件視爲弱類型的字典,則需要在每個事件處理程序中執行 重複。另一方面,如果您將事件和命令視爲強類型,則您的反序列化器可以是您必須維護的單個容錯讀取器。
類型
這一切說,我能理解你爲什麼,如C#或Java語言,發現,定義爲每一位消息不可改變的DTO似乎是一個很大的開銷:
public sealed class CorrectNameCommand
{
private readonly string userId;
private readonly string newName;
public CorrectNameCommand(string userId, string newName)
{
this.userId = userId;
this.newName = newName;
}
public string UserId
{
get { return this.userId; }
}
public string NewName
{
get { return this.newName; }
}
public override bool Equals(object obj)
{
var other = obj as UserName;
if (other == null)
return base.Equals(obj);
return object.Equals(this.userId, other.userId)
&& object.Equals(this.newName, other.newName);
}
public override int GetHashCode()
{
return this.userId.GetHashCode()^this.newName.GetHashCode();
}
}
那的確,好像很多工作。
這就是我最近更喜歡其他語言來實現CQRS的原因。上 。NET,F#是一個完美的結合,因爲所有上面的代碼歸結爲一個班輪:
type CorrectNameCommand = { UserId : string; NewName : string }
這就是我想要做的,而不是通過弱類型周圍字典。上次我聽說格雷格揚談論CQRS(NDC奧斯陸2015)時,他似乎也「轉換」爲F#。
我會說這是關於可讀性和明確。您會看到Command需要什麼,並且您可以看到Event提供的內容。重要價值對在這裏不是很有幫助。同樣使用命名約定,很容易使用Ioc-Container來創建正確的Command和EventHandler。 – Jehof
所以這是一個折衷?我還編寫了一個通用命令處理程序,該處理程序可以自動調度到ag上具有匹配名稱和匹配參數的方法。這甚至消除了爲每個命令編寫命令處理程序的工作(但不禁止它)。 –
這不是說你有一個有很多方法處理你的命令的大類嗎?而不是一個類處理每個命令? –