命令和事件有什麼區別? - Oskar
命令代表意圖:它針對特定的受眾。當你問“把鹽遞給我”時,它可以是你的朋友。它可以是一個應用服務和請求,意圖是“新增使用者”或“將訂單狀態更改為已確認”。所以命令的傳送者必須知道接收者並期望請求被執行。當然,接收者可能會拒絕這樣做,因為在請求處理期間不向我們傳遞鹽或丟擲異常。
事件代表了過去的事實:它攜帶有關已完成某事的資訊。所見所聞,不可不察。按照我們的例子“使用者新增”,“訂單狀態更改為確認”是過去的事實。我們不會將事件定向到特定的接收者,我們會廣播資訊。這就像在聚會上講故事一樣。我們希望有人傾聽我們,但我們可能很快就會意識到沒有人在關注。
事件和命令有什麼共同點?
兩者都是訊息。它們傳達特定的資訊;關於做某事的意圖的命令,或關於發生的事實的事件。從計算機的角度來看,它們沒有什麼不同。只有業務邏輯和訊息的解釋才能發現事件和命令的區別。
通常假設命令是同步的,而事件是非同步的。我們通常透過例如 Rest API 傳送命令,透過佇列(記憶體中、RabbitMQ、Kafka 等)傳送事件。這種區別來自習慣。當我們傳送命令時,我們想立即知道它是否已經完成。通常,我們希望在操作失敗時進行替代方案或錯誤處理。同樣,我們通常假設最好立即停止該過程,例如購買電影票,而不是等待並重新整理並檢視它是否有效。
這是有道理的,但並不總是那麼明顯。例如,銀行轉賬:當我們成功時,它不會立即發生。我們得等一會兒。在 Internet 上進行購買時也是如此。下訂單和付款不會立即完成整個過程。它還是要發貨,發票開具等等。這是一個非同步過程,所以我們的命令的結果也可能是非同步的。
微服務和分散式系統增加了額外的複雜性。
傳統上,發件人需要知道該告訴誰來接管其餘的工作。使用排隊/流系統逆轉服務的依賴性。傳送者將訊息釋出到統一頻道,接收者訂閱並等待。當我們購買電影票時,必須生成收據,必須預訂座位,並透過電子郵件通知使用者並在網站上顯示。所有這些都可以拆分為單獨的工作流程步驟。哪個應該由命令觸發,哪個應該由事件觸發?
我們可以使用啟發式:當接收者有權拒絕請求時,我們傳送命令,當接收者接受時傳送事件。如果我們要新增使用者,系統可能會拒絕我們使用現有使用者名稱。金融服務可以拒絕預訂服務生成收據嗎?如果預訂被確認,轉賬已經完成,那麼財務模組應該接受它。那麼,這是一個事件嗎?
理論上,是的,如果沒有驗證規則並且事件發生了,另一個系統應該接受它並執行邏輯。即使金融服務暫時不可用,類似 Kafka 的流媒體系統也應保證交付。我們在程式碼中有錯誤?然後我們必須修復它們。
到這裡,理論結束,實踐開始。我們的客戶不在乎錯誤是否是我們知道並在不久的將來修復的錯誤?客戶想要開展業務並運營。
當然,在訊息佇列教程中,你可以找到這樣的建議:“有一個死信佇列/毒訊息佇列,未處理的訊息將被放置在那裡。你可以在那裡檢查並做出反應”。這很酷,但有多少人在監視它?即使他們這樣做了,他們能多快做出反應?假設我們收集指標、傳送警報、快速支援響應並向程式設計師報告“票”。他們會多快修復它?我們可以透過預先設計並新增補償操作(例如,如果預訂確認事件丟失時在 UI 中生成發票的按鈕)來簡化這一點。
有時事實證明,一個給定的事件總是隻有一個接收者。更重要的是,我們希望它始終得到處理。它仍然是一個事件嗎?值得考慮的是,在名稱為“預訂已確認”的事件下,我們是否不傳送“發出收據”命令。當業務流程至關重要時,我們可能更願意快速失敗並立即獲得結果。對於這種情況,值得考慮是否執行非同步命令比執行非同步事件更好。
命令和事件之間的區別可能並不像看起來那麼簡單。我們需要考慮很多因素:
- 是有意做某事還是記錄的事實?
- 是非同步操作還是同步操作?
- 它可以有多個收件人嗎?
- 它是關鍵業務嗎?
- 還有很多
如果有人問你“這是一個命令還是一個事件”,不要害怕說“這取決於”,然後開始著手理解業務邏輯。
相關文章
- React事件與普通HTML事件有什麼區別React事件HTML
- *和body有什麼區別
- Cache 和 Buffer 有什麼區別?
- mongodb和mysql有什麼區別MongoDBMySql
- shim和polyfill有什麼區別
- float和double有什麼區別?
- int 和 Integer 有什麼區別
- cookie和session 有什麼區別?CookieSession
- session 和 cookie 有什麼區別?SessionCookie
- modbus和tcp有什麼區別?TCP
- Nginx和Apache有什麼區別?NginxApache
- COOKIE和SESSION有什麼區別?CookieSession
- RegisterClass和RegisterClassEx有什麼區別?
- for update 和 for update of 有什麼區別
- PEAR 和 PECL 有什麼區別?
- Activity和Fragment有什麼區別Fragment
- vue和react有什麼區別?VueReact
- Iterator和ListIterator有什麼區別
- Hifi和ONT 有什麼區別
- DOM和BOM有什麼區別?
- cookie是什麼?和session有什麼區別?CookieSession
- IPFS和區塊鏈有什麼區別區塊鏈
- Java和Python是什麼?有什麼區別?JavaPython
- RPA和IPA有什麼區別
- Jsp和Servlet有什麼區別?JSServlet
- HTTP和HTTPS有什麼區別?HTTP
- VPS和HTTP有什麼區別?HTTP
- c++中&和&&有什麼區別C++
- DAO和Repository有什麼區別
- 青蛙和癩蛤蟆有什麼區別
- maven </dependencies>和</dependencyManagement> 有什麼區別Maven
- JMS和AMQP有什麼區別嗎MQ
- 什麼是報表工具?和 EXCEL 有什麼區別?Excel
- Java 介面和抽象類是什麼,有什麼區別Java抽象
- 什麼是 MicroPython?和CPython有什麼區別?Python
- 什麼是SCRM系統?和CRM有什麼區別?
- png是什麼格式 png和jpg有什麼區別
- xpgu是什麼 xgpu和xgp有什麼區別GPU