契約式設計規定方法應該對輸入和輸出進行驗證,這樣你便可以保證你得到的數據是可以工作的,一切都是按預期進行的,如果不是按預期進行,異常或是錯誤就應該被返回,下面我們舉的例子中,我們方法中的參數可能會值爲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;
}
}
}