2015-06-30 39 views
3

在我看到的大多數例子中,命令和事件都表示爲類。這意味着你必須編寫一個帶有name屬性的CorrectNameCommand類和一個帶有name屬性的NameCorrectedEvent類。鑑於命令和事件在大多數情況下都是序列化和反序列化的,併發送給其他方(編譯時安全類型),這個顯式類相對於更通用的類有什麼優勢?CQRS Commands and Events as generic classes?

實施例:

用名稱(即表示命令的類型)

A命令類時,AG的應處理的命令和對象或名稱/值對的任何陣列的關鍵其他參數。

一個Event類本質上是相同的(也許我們可以把共享部分放在一個CommandEventBase類中)。

命令(和事件)處理程序現在要檢查命令(事件)的名稱而不是它的類類型,並且必須依賴列表中參數的正確性(就像解串器必須依賴序列化格式正確)。

這是一個很好的方法嗎?如果是的話,爲什麼它不被用在樣本和教程中?如果不是,有什麼問題?

+1

我會說這是關於可讀性和明確。您會看到Command需要什麼,並且您可以看到Event提供的內容。重要價值對在這裏不是很有幫助。同樣使用命名約定,很容易使用Ioc-Container來創建正確的Command和EventHandler。 – Jehof

+0

所以這是一個折衷?我還編寫了一個通用命令處理程序,該處理程序可以自動調度到ag上具有匹配名稱和匹配參數的方法。這甚至消除了爲每個命令編寫命令處理程序的工作(但不禁止它)。 –

+0

這不是說你有一個有很多方法處理你的命令的大類嗎?而不是一個類處理每個命令? –

回答

6

複製

這是一個公平的一點是,當命令和事件序列化,編譯時安全性丟失,但在一個靜態類型語言,我還是更喜歡強類型的命令和事件類型。

原因是它給了你一個負責解釋消息元素的代碼庫。序列化往往是相當(類型)安全的;反序列化是您可能遇到問題的地方。

不過,我寧願在一個地方處理任何這樣的問題,而不是分散在整個代碼庫中。

這對事件特別重要,因爲您可能有多個事件處理程序處理相同類型的事件。如果您將事件視爲弱類型的字典,則需要在每個事件處理程序中執行 重複。另一方面,如果您將事件和命令視爲強類型,則您的反序列化器可以是您必須維護的單個容錯讀取器。

類型

這一切說,我能理解你爲什麼,如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#。

+0

轉換爲F#對我來說不是短時間選項。 :-)因此,也許最好的方式是使用像你在F#中編寫的DSL一樣的東西,並生成C#。 –

+2

您是否考慮過在F#中定義類型,並將它們打包到庫中?從C#開始,這些記錄將看起來像不可變的類(基本上與我的C#示例中的CorrectNameCommand類沒有區別;這就是它們編譯的內容)。 –

+0

好主意。我會試一試。謝謝。 –