想定される状況なのに例外を使用している場合は「条件判定による例外の置き換え」を検討します。
たとえば「クーポンがある場合とない場合で割引価格を変更する」処理が以下のように定義されていたとします。
// 販売価格を取得します
private decimal GetSalePrice(bool hasCoupon, decimal listPrice)
{
try
{
return GetDiscountPrice(hasCoupon, listPrice);
}
catch
{
return GetDiscountPriceHasCoupon(listPrice);
}
}
// 割引価格を取得します
private decimal GetDiscountPrice(bool hasCoupon, decimal listPrice)
{
// クーポンがある場合
if (hasCoupon == true)
{
throw new Exception();
}
return listPrice * 0.9M;
}
// 割引価格を取得します(クーポンあり)
private decimal GetDiscountPriceHasCoupon(decimal listPrice)
{
return listPrice * 0.8M;
}
見た目はまあまあ整っていますが、「クーポンがある場合」という正常系の処理に例外を使用している個所が問題です。
それでは「条件判定による例外の置き換え」のリファクタリングを適用してみましょう。
// 販売価格を取得します
private decimal GetSalePrice(bool hasCoupon, decimal listPrice)
{
// クーポンがある場合
if (hasCoupon == true)
{
return GetDiscountPriceHasCoupon(listPrice);
}
else
{
return GetDiscountPrice(listPrice);
}
}
// 割引価格を取得します(クーポンあり)
private decimal GetDiscountPriceHasCoupon(decimal listPrice)
{
return listPrice * 0.8M;
}
// 割引価格を取得します
private decimal GetDiscountPrice(decimal listPrice)
{
return listPrice * 0.9M;
}
クーポンがある場合とない場合は「等しく発生する事象」ですので、「if – else」の条件判定で判断しそれぞれ割引価格取得用のメソッドを呼び分けています。