リファクタリングの実例3

Advertisement

エラーコードを例外に置き換える

従来の例外メカニズムを備えていない言語では、エラー判定はリターンコードを使用して行っていた。

サンプルコード
public class Returncode {
    float money;
    float tax;
    float pay;

    public Returncode(float money){
        this.money = money;
        tax = money * 1.05f;
    }

    public int Calc(){
        if(money < 0){
            return -1;  // 異常終了
        }
        pay = money + tax;
        return 0;  // 正常終了
    }
}

クライアント
import java.util.Vector;
public class Main {
    public static void main(String[] args) {
        Vector list = new Vector();

        Returncode ret = new Returncode(100);
        Returncode err = new Returncode(-50);

        int i = ret.Calc();
        if(i == 0){
            list.add(ret);
        }

        int j = err.Calc();
        if(j == 0){
            list.add(err);
        }
    }
}

メソッドを呼び出し、呼び出し側で戻り値を確認する。しかし、この方法だと戻り値チェックを記述しなくてもコードは先に進むことができるため、チェックを怠った場合、発生したエラーは後続のプログラムにまで影響を及ぼしてしまう。

問題のあるコード
import java.util.Vector;
public class Main {
    public static void main(String[] args) {
        Vector list = new Vector();

        Returncode ret = new Returncode(100);
        Returncode err = new Returncode(-50);

        int i = ret.Calc();
        list.add(ret);

        int j = err.Calc();
        list.add(err);
    }
}
この場合、errオブジェクトはエラーを含んでいるにも関わらずリストに追加されてしまっている。

例外に置き換える

Javaでは強力な例外処理メカニズムを備えているため、従来の方法よりも安全にエラー処理を行うことができる。
public class ThrowException {
    float money;
    float tax;
    float pay;

    public ThrowException(float money){
        this.money = money;
        tax = money * 1.05f;
    }

    public int Calc() throws InaccurateException{
        if(money < 0){
            // 異常終了
            throw new InaccurateException();
        }
        pay = money + tax;
        return 0;  // 正常終了
    }
}

例外
class InaccurateException extends Exception{}

クライアント
import java.util.Vector;
public class Main {
    public static void main(String[] args) {
        Vector list = new Vector();

        ThrowException th = new ThrowException(100);
        try{
            th.Calc();
            list.add(th);
        }catch(InaccurateException ie){
            ie.printStackTrace();
            System.exit(-1);
        }
    }
}

try-catchを記述しないとコンパイルが成功しないため、例外の補足を忘れることはなくなり、一定の安全性が保証される。ただし、このメソッドが様々な場所から呼ばれている状態でリファクタリングを行う場合、修正箇所が多く存在することになるため注意が必要。本来ならシステム設計の時点で例外の設計もきちんと行うことが望ましい。

また、従来どおりリターンコードで終了判定を行う方が望ましい場合も存在するので見極めが重要である。

Advertisement

ショートカット

634トップページ
このカテゴリのトップページに戻る
634ラボ

サイト検索

Google

Web サイト内

Y!ログール