例外処理には 2 つのアプローチがあることを知っています。それらを見てみましょう。
契約アプローチ。
メソッドがメソッド ヘッダーで実行すると述べていることを実行しない場合、例外がスローされます。したがって、メソッドは操作を実行することを「約束」し、何らかの理由で失敗した場合は例外をスローします。
例外的なアプローチ。
本当に奇妙なことが起こった場合にのみ、例外をスローします。通常の制御フロー (If ステートメント) で状況を解決できる場合は、例外を使用しないでください。コントラクト アプローチの場合のように、制御フローに例外を使用しません。
さまざまなケースで両方のアプローチを使用してみましょう。
OrderProduct というメソッドを持つ Customer クラスがあります。
契約アプローチ:
class Customer
{
public void OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
throw new NoCreditException("Not enough credit!");
// do stuff
}
}
例外的なアプローチ:
class Customer
{
public bool OrderProduct(Product product)
{
if((m_credit - product.Price) < 0)
return false;
// do stuff
return true;
}
}
if !(customer.OrderProduct(product))
Console.WriteLine("Not enough credit!");
else
// go on with your life
ここでは例外的なアプローチを好みます。なぜなら、顧客が宝くじに当選しなかったと仮定してお金を持っていないということは、真に例外的ではないからです。
しかし、これは私が契約スタイルを誤っている状況です。
優れた:
class CarController
{
// returns null if car creation failed.
public Car CreateCar(string model)
{
// something went wrong, wrong model
return null;
}
}
CreateCar というメソッドを呼び出すと、実行中のコードを数十行後に破壊する可能性のあるお粗末な null ポインターではなく、Car インスタンスが期待されます。したがって、私はこれよりも契約を好みます。
class CarController
{
public Car CreateCar(string model)
{
// something went wrong, wrong model
throw new CarModelNotKnownException("Model unkown");
return new Car();
}
}
あなたはどちらのスタイルを使いますか?例外に対する最も一般的なアプローチは何だと思いますか?