iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0

昨天提到回傳boolean或錯誤碼帶來的問題

  1. 當方法中有有其他異常流程需要處理時,會需要更多判斷來控制流程,讓最後結果只有一個錯誤碼
  2. 如果從UI到底層都需要處理錯誤碼,中間流程的回傳值就容易被限制。

今天我們會針對上面的問題,使用Exception改善這些問題。以昨天的例子來說

public class OrderService
{
		private readonly IOrderRepository _orderRepository;

    ...
    
    public OrderStatus Save(Order order)
    {
        return _orderRepository.Save(order);
    }
}

如果把它調整成使用Custom Exception

public class OrderService
{
		private readonly IOrderRepository _orderRepository;

    ...
    
    public void Save(Order order)
    {
        var orderStatus = _orderRepository.SaveOrder(order);
        if (orderStatus == OrderStatus.Rejected)
        {
            throw new OrderRejectedException(order);
        }
    }
}

這樣一來TransactionService就可以透過catch攔截OrderRejectedException來處理異常流程。如果外部需要知道Rejected狀態時,也能透過throw把Exception再次丟出。

public class TransactionService
{
    private readonly OrderService _orderService;

    ...
    
    public void Save(int userId, int goodsId)
    {
        var order = new Order(GetUser(userId), GetGoods(goodsId));
        try
        {
            _orderService.Save(order);
        }
        catch (OrderRejectedException e)
        {
            Refund(order);
						throw;
        }
    }
}

在Action就不需要接取orderStatus處理成功的情況,而是利用try catch處理錯誤情況。如果是ASP.NET就能使用ActionFilter把錯誤流程移出去,讓Action裡面只剩下主要流程。

public IActionResult Confirm(int userId, int goodsId)
{
    try
    {
        _transactionService.Save(userId, goodsId);
        return Ok();
    }
    catch (OrderRejectedException)
    {
        return BadRequest();
    }
}

假設Refund也有錯誤流程需要處理時,也能透過拋出Exception讓其他方法去處理。

讓錯誤流程透過拋出Exception的方式來控制流程,這種做法最大的好處就是需要處理的地方透過try catch的方式去處理,其他中間類別或方法就能維持其正常流程,不需要每個環節都要考慮異常狀態時要如何傳回錯誤碼。

另外一個優點是能將主要流程凸顯在try中,讓閱讀代碼的人可以一看明白什麼是主要流程、什麼是錯誤處理流程。


上一篇
Day 16 當錯誤發生時(上)
下一篇
Day 18 變數宣告在哪邊
系列文
在Kata中尋找Clean Code是否搞錯了什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言