引入契約式設計

契約式設計規定方法應該對輸入和輸出進行驗證,這樣你便可以保證你得到的數據是可以工作的,一切都是按預期進行的,如果不是按預期進行,異常或是錯誤就應該被返回,下面我們舉的例子中,我們方法中的參數可能會值爲null的情況,在這種情況下由於我們沒有驗證,NullReferenceException異常會報出。另外在方法的結尾處我們也沒有保證會返回一個正確的decimal值給調用方法的對象。

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LosTechies.DaysOfRefactoring.SampleCode.Day25_DesignByContract
{
    public class CashRegister
    {
        public decimal TotalOrder(IEnumerable<Product> products, Customer customer)
        {
            decimal orderTotal = products.Sum(product => product.Price);

            customer.Balance += orderTotal;

            return orderTotal;
        }
    }
}

對上面的代碼重構是很簡單的,首先我們處理不會有一個null值的customer對象,檢查我們最少會有一個product對象。在返回訂單總和之前先確保我們會返回一個有意義的值。如果上面說的檢查有任何一個失敗,我們就拋出對應的異常,並在異常裏說明錯誤的詳細信息,而不是直接拋出NullReferenceException。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Contracts;

namespace LosTechies.DaysOfRefactoring.SampleCode.DesignByContract.After
{
    public class CashRegister
    {
        public decimal TotalOrder(IEnumerable<Product> products, Customer customer)
        {
            if (customer == null)
                throw new ArgumentNullException("customer", "Customer cannot be null");
            if (products.Count() == 0)
                throw new ArgumentException("Must have at least one product to total", "products");

            decimal orderTotal = products.Sum(product => product.Price);

            customer.Balance += orderTotal;

            if (orderTotal == 0)
                throw new ArgumentOutOfRangeException("orderTotal", "Order Total should not be zero");

            return orderTotal;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章