K's Atelier

個人的な学習記録

例外処理があると何がうれしいのか

例外処理は新人研修の鬼門の一つ。
やりたいことは単純なのだが,いかんせん現代のプログラミング言語は例外処理が実装されているのが当前なので,例外処理がなかった時代のコードがテキストに載っていない。
例外処理がなぜ有効なのかを説明するコードを書いたら,久しぶりに昔のC言語を思い出した。

例外処理なし

package 例外処理なし;

public class 検索結果 {
    private String 結果;
    private int 状態;

    public 検索結果(String 結果, int 状態) {
          this.結果 = 結果;
          this.状態 = 状態;
    }

    public String get結果() {
        return 結果;
    }

    public int get状態() {
        return 状態;
    }

}
package 例外処理なし;

public class データベース {

    public 検索結果 問い合わせ(String 問い合わせ文, String 文字コード) {
        if (問い合わせ文 == null) {
            return new 検索結果(null,-1);
        }
        if (文字コード == null) {
            return new 検索結果(null,-2);
        }
        return new 検索結果("100,90,75",0);
    }

}
package 例外処理なし;

public class データベースクライアント {

    public static void main(String[] args) {
        データベース db = new データベース();

        検索結果 結果;

        結果 = db.問い合わせ("SELECT * FROM SCORE", "UTF-8");

        if (結果.get状態() == -1) {
            System.out.println("正しい問い合わせ文を指定してください");
        } else if (結果.get状態() == -2) {
            System.out.println("正しい文字コードを指定してください");
        }
        if (結果.get状態() == 0) {
            System.out.println(結果.get結果());
        }

        結果 = db.問い合わせ(null, "UTF-8");
        if (結果.get状態() == -1) {
            System.out.println("正しい問い合わせ文を指定してください");
        } else if (結果.get状態() == -2) {
            System.out.println("正しい文字コードを指定してください");
        }
        if (結果.get状態() == 0) {
            System.out.println(結果.get結果());
        }

        結果 = db.問い合わせ("SELECT * FROM INSTRUCTOR", null);
        if (結果.get状態() == -1) {
            System.out.println("正しい問い合わせ文を指定してください");
        } else if (結果.get状態() == -2) {
            System.out.println("正しい文字コードを指定してください");
        }
        if (結果.get状態() == 0) {
            System.out.println(結果.get結果());
        }

        System.out.println("データベース接続を切断します");
    }
}

例外処理がない時代は,戻り値で表現するか,特定メモリにステータスを書く処理を実装するしかなかった。
どんなに頑張っても,正常処理と例外処理が混在することが避けられない。
このコードを(色分けして)見せないと,なぜ例外処理が言語機能として必要なのか,理解できないだろう。

例外処理あり

package 例外処理あり;

public class 検索結果 {
    
    private String result;

    public 検索結果(String result) {
        this.result = result;
    }

    public String getResult() {
        return result;
    }

}
package 例外処理あり;

public class 文字コード例外 extends Exception {

    public 文字コード例外(String string) {
        super(string);
    }

}
package 例外処理あり;

public class 問い合わせ例外 extends Exception {

    public 問い合わせ例外(String string) {
        super(string);
    }

}
package 例外処理あり;

public class データベース {

    public 検索結果 問い合わせ(String 問い合わせ文, String 文字コード) throws 問い合わせ例外, 文字コード例外 {
        if (問い合わせ文 == null) {
            throw new 問い合わせ例外("不正な問い合わせ文です");
        } else if (文字コード == null) {
            throw new 文字コード例外("不正な文字コードです");
        } else {
            return new 検索結果("100,80,75");
        }
    }
}
package 例外処理あり;
public class データベースクライアント {

    public static void main(String[] args) {
        データベース db = new データベース();
        
        try {
            検索結果 結果;
            結果 = db.問い合わせ("SELECT * FROM SCORE","UTF-8");
            System.out.println(結果.getResult());
            結果 = db.問い合わせ(null,"UTF-8");
            System.out.println(結果.getResult());
            結果 = db.問い合わせ("SELECT * FROM INSTRUCTOR",null);
            System.out.println(結果.getResult());
        } catch (問い合わせ例外 e) {
            System.out.println("正しい問い合わせ文を指定してください");
            System.out.println(e.getMessage());
        } catch (文字コード例外 e) {
            System.out.println("正しい文字コードを指定してください");
            System.out.println(e.getMessage());
        } finally {
            System.out.println("データベース接続を切断します");
        }
    }
}

余談:モデリング言語としてのJava

Javaは識別子名に日本語を割と自由に使える。この機能はモデリングにおいて非常に強力な武器になる。
この点,RubyHaskellは識別子名がアルファベット前提になってしまっており,不便を感じる。
教育をする上では,分かりやすいサンプルにするのが基本だ。
分からない言語機能を,不慣れな英語で読み解くのは受講者に不親切だろう。