領域驅動設計中的異常 - Michał
異常已經被引入來處理函式層面的錯誤。其目的是為了避免返回錯誤程式碼和消除返回型別的模糊性。異常的力量來自於它們透過堆疊向下傳播的能力。你沒有義務直接處理異常。它允許你將你的正常程式碼流與錯誤處理分開。
當函式對引數的假設被打破或者函式不能履行其承諾時,應該丟擲一個異常。最簡單的例子是除以0。我們必須向呼叫者發出訊號,表示我們不能提供答案。這個異常構成了函式契約的一部分。在語言學中,這有時被稱為預設失敗。考慮一下法國國王是否是禿頭的問題。沒有法國國王,所以我們不能用是或不是來回答。任何一個答案都會產生誤導。
異常是領域語言的一部分
把異常作為領域語言本身的一部分來考慮是很方便的。這是一種很好的交流方式。像OrderLimitExceeded這樣的業務異常是很重要的,而且資訊量很大。透過翻閱異常列表,你可以獲得關於業務預期的基本資訊。有必要建立一個一致的領域異常的層次結構。例如,如果你的訂單集合可能會引發許多不同的異常,作為其API的一部分,所有這些異常都應該擴充套件為一個單一的異常,如OrderException。這使它更容易處理。事實上,控制異常流並不是一件容易的事,它需要大量的紀律性。否則,它遲早會失去控制。
異常的問題
不幸的是,異常並不理想。它們破壞了程式碼的自然控制流。它是變相的GOTO。使用異常還增加了介面的複雜性,增強了耦合性。丟擲異常會破壞引用的透明度,所以我們的方法並不純粹。我們的函式沒有單一的返回點,這大大阻礙了推理。
異常還有一個巨大的問題。異常可能導致模型的不一致狀態。如果某些操作無法完成,模型應該保持與之前相同的狀態。開發者並不總是注意到這一點。在計算過程中,模型狀態只被部分改變並且不一致的情況下,就會引發異常。你的IDE和編譯器都不會幫助你解決這個問題。
最近的一項研究表明,分散式系統中90%的故障是指錯誤處理。
功能性方法
使用類似單體的容器型別,如Option、Either或Result,可讀性和優雅性要好得多。這些都是注重功能的語言中眾所周知的結構。我們可以在設計我們的API時只考慮單一的返回型別,而不去扭曲控制流。
Order.addItem(Item $item): Either[Order, Error] |
新增一個專案可能導致一個新的訂單(包含該專案)或一個錯誤。指定我們可能從該方法得到的錯誤型別(OrderItemsNumberExceed, CanNotAddItemToFinishedOrder)是至關重要的。該API是優雅而完整的。返回型別明確地告訴我們,我們可能沒有任何引數的有效答案。我們可以使用聯合型別或通用的OrderError,並在方法文件中描述這些錯誤,但依賴型別級的安全總是更好。
在語言層面上,必須可以輕鬆地對許多呼叫進行排序,而不必為錯誤處理而煩惱。如果是這樣的話,那是非常好的。
選項、任一、結果--保留單體特徵的型別很容易被組合。這不會破壞正常的控制流或參考透明性。但是如果沒有語言層面上的語法支援,可能會變成很麻煩。否則,例外可能是更有吸引力的選擇。
免責宣告
這篇文章只提到了商業領域的環境,可能不適用於低階別的或基礎設施的情況。
相關文章
- JavaScript中的領域驅動設計JavaScript
- DDD領域驅動設計:領域事件事件
- MasaFramework -- 領域驅動設計Framework
- 領域驅動設計示例
- 理解領域驅動設計
- 領域驅動設計,中臺與微服務微服務
- 戲說領域驅動設計(廿五)——領域事件事件
- 領域驅動設計戰術模式--領域事件模式事件
- 領域驅動設計核心概念
- 領域驅動設計簡介
- DDD領域驅動設計pdf
- 再談領域驅動設計
- 實現領域驅動設計
- 整潔的領域驅動設計 - George
- 問題驅動設計與領域驅動設計的區別 - abdullin
- 戲說領域驅動設計(廿一)——領域服務
- 領域驅動設計戰術模式--領域服務模式
- DDD-領域驅動設計示例
- 微服務領域驅動設計 - semaphoreci微服務
- 淺談DDD(領域驅動設計)
- 淺談 DDD 領域驅動設計
- 何時使用領域驅動設計
- DDD領域驅動設計:倉儲
- 前端開發-領域驅動設計前端
- 戲說領域驅動設計(五)——子域
- 領域驅動設計(DDD)中模型的重要性 - Jeronimo模型
- 領域驅動設計中的聚合是什麼? - James Hickey
- 領域驅動設計對依賴的控制
- 領域驅動設計的DDD與ddd - nick
- 領域驅動設計的概念解釋 -DEVdev
- “親切照料”下的領域驅動設計
- 聊一聊中臺和DDD(領域驅動設計)
- 最常見領域驅動設計錯誤
- 領域驅動設計整合與架構架構
- dayatang/dddlib:DDD領域驅動設計庫
- 戲說領域驅動設計(廿二)——聚合
- 戲說領域驅動設計(三)——困境
- DDD-領域驅動設計簡談