設計Akka.NET領域事件和命令的最佳實踐 | Petabridge
這是一篇.NET中Akka的領域事件和命令設計文章,闡述如何透過設計事件使Akka.NET程式設計更容易。詳細點選標題見原文:
1. 慷慨地使用標記/身份介面
如果我們有大量的域事件用於交易股票,所有這些事件都有幾個常見的識別符號和屬性,對於路由,分片或分發這些訊息非常有用:
- 股票程式碼(MSFT,TEAM,AMD等......);
- 訂單的ID;
- 它們都代表由於交易者活動而發生的實時交易事件 - 這與交易所發出的事件不同,該事件表明特定股票程式碼的最新“市場價格”是什麼。
2. 始終使您的域訊息不可變
這是因為如果您向同一程式內的本地執行的許多actor傳送相同的訊息 - 所有這些actor都會收到對該訊息的同一副本的引用。如果您使此訊息型別變為可變,如果一個actor修改此訊息上的任何屬性或欄位,那些更改將傳播到處理相同訊息的所有其他actor - 這就是所謂的在併發程式設計中“副作用” 。
因此,我們需要確保預設情況下在actor之間傳送的所有域訊息都是不可變的。以下是如何做到這一點:
- 將所有屬性和欄位設定為只讀 - 可以透過訊息的建構函式設定值的唯一方法;
- 切勿將正常集合,即List<T>或Dictionary<K,V>,作為一個訊息類的屬性-總是暴露System.Collections.Generic集合為IReadOnlyCollection<T>,IReadOnlyList<T>,IReadOnlyDictionary<K,V>,等;
- 確保傳遞給訊息建構函式的物件本身是不可變的。
3. 可以輕鬆將域實體複製到不可變訊息中
根據我們的“如何使您的訊息不可變”清單中的第3項,確保您的actor透過不可變訊息與其他actor共享的資料也是不可變的本身是一種很好的做法。
我們將所有內部狀態複製到新集合中並將其返回到不可變訊息中。
4. 將ToString()方法重寫為漂亮輸出領域事件
在對生產進行故障排除時,Akka.NET系統開發人員通常依賴於Akka.NET的日誌記錄基礎設施和Phobos actor跟蹤等工具- 但從這些系統中獲取良好資訊通常需要詳細列印出在整個系統中傳播的關鍵訊息的內容。
管理此方法的最簡單方法是覆蓋object.ToString()每個域事件上的方法,並將其自定義為“非常列印”事件的狀態。
/// <summary> /// Concrete <see cref="IPriceUpdate"/> implementation. /// </summary> public sealed class PriceChanged : IPriceUpdate, IComparable<PriceChanged> { public PriceChanged(string stockId, decimal currentAvgPrice, DateTimeOffset timestamp) { StockId = stockId; CurrentAvgPrice = currentAvgPrice; Timestamp = timestamp; } public DateTimeOffset Timestamp { get; } public decimal CurrentAvgPrice { get; } public string StockId { get; } public int CompareTo(PriceChanged other) { if (ReferenceEquals(this, other)) return 0; if (ReferenceEquals(null, other)) return 1; return Timestamp.CompareTo(other.Timestamp); } public int CompareTo(IPriceUpdate other) { if (other is PriceChanged c) { return CompareTo(c); } throw new ArgumentException(); } public override string ToString() { return $"[{StockId}][{Timestamp}] - $[{CurrentAvgPrice}]"; } } |
當您遵循這種方法時,所有關於如何將域事件呈現為文字的邏輯都會成為訊息本身的一部分,以及許多不同的基礎結構,這些基礎結構可能都需要列印出訊息的內容(日誌記錄,異常)處理等...如果ToString()正確實施,都可以使用一致的顯示格式。
相關文章
- 事件風暴 - 分解問題領域的最佳實踐事件
- 領域驅動設計最佳實踐--程式碼篇
- 結合領域事件和微服務的實現領域驅動設計 - Alagarsamy事件微服務
- DDD領域驅動設計:領域事件事件
- Serverless 在 SaaS 領域的最佳實踐Server
- 領域驅動設計(DDD)實踐之路(二):事件驅動與CQRS事件
- Laravel最佳實踐–事件驅動程式設計Laravel事件程式設計
- Laravel 最佳實踐 -- 事件驅動程式設計Laravel事件程式設計
- Laravel最佳實踐 -- 事件驅動程式設計Laravel事件程式設計
- 基於ABP落地領域驅動設計-02.聚合和聚合根的最佳實踐和原則
- 領域驅動設計戰術模式--領域事件模式事件
- 戲說領域驅動設計(廿五)——領域事件事件
- 領域驅動模型DDD(二)——領域事件的訂閱/釋出實踐模型事件
- 基於ABP落地領域驅動設計-03.倉儲和規約最佳實踐和原則
- 領域驅動設計:CQRS 和事件源的強大功能事件
- 領域驅動設計(DDD)實踐之路(一)
- 領域驅動設計實踐——驗證(一)
- 領域驅動設計DDD和CQRS架構模式落地實踐架構模式
- EntityFramework之領域驅動設計實踐介紹Framework
- Chronicle事件溯源的最佳實踐事件
- 領域驅動設計實踐:支付系統建模 - Xiao
- 《實現領域驅動設計》筆記——領域、子域和限界上下文筆記
- 設計微服務的最佳實踐微服務
- 去哪兒網領域驅動設計(DDD)實踐之路
- MaxCompute表設計最佳實踐
- 重新整理 .net core 實踐篇—————領域事件[二十九]事件
- 實現領域驅動設計
- 微服務與領域驅動設計,架構實踐總結微服務架構
- 領域驅動設計在重構業務系統中的實踐
- Node之道:設計、架構和最佳實踐 | Alex Kondov架構
- Devops是數字化轉型在IT領域的一個最佳實踐dev
- 領域事件和整合事件沒那麼高大上事件
- react 設計模式與最佳實踐React設計模式
- 13 個設計 REST API 的最佳實踐RESTAPI
- Vue 在大型專案中的架構設計和最佳實踐Vue架構
- 資料庫設計的十個最佳實踐資料庫
- Java程式設計師的八個最佳實踐Java程式設計師
- Python程式設計規範+最佳實踐Python程式設計