「Javaプログラミング能力認定試験課題プログラムのリファクタリングレポート」に触発されて

ryoasai さんの「Javaプログラミング能力認定試験課題プログラムのリファクタリングレポート」に触発されたので、
Java の勉強がてら、同様なプログラムを作成してみる。

Step 13

人材データ更新時、以下の状態で、"N" を入力したとき

以下の内容で更新します。
人材ID : 7
氏名 : 山田 太郎
...略...
希望単価 : 1000円
 [Y, N]>

人材IDの入力に戻ってしまうのではなく、

 [Y, N]>N

人材IDを入力してください。
 [人材ID, E]>

更新を続行したいので、

 [Y, N]>N

更新したい項目を選択してください。
1.氏名
...略...
12.希望単価
 [1-12, E]>

変更してみた

処理フローを 制御する 抽象クラス

abstract class AbstractDispatcher {
    protected BufferedReader reader;
    protected boolean hasEndCommand = true;

    protected boolean run(BufferedReader reader) {
        this.reader = reader;

        while (true) {
            // 選択肢 を 表示
            beforeDisplayMenu();
            
            // 処理 を 選択
            String inputCode = printMenuAndWaitForInput();

            // 終了?
            if (isEndCommand(inputCode)) break;
            
            // 選択した処理 を 実行
            if (runFunction(inputCode)) break;
        }

        // 処理結果を 返す (これを追加した)
        return getResult();
    }

    // 選択肢 を 表示
    protected abstract void beforeDisplayMenu();

    // 処理 を 選択
    protected String printMenuAndWaitForInput() {
        String inputCode;
        try {
            inputCode = reader.readLine();

        } catch (Exception e) {
            e.printStackTrace();
            inputCode = null;
        }

        return inputCode;
    }

    // 終了?
    protected boolean isEndCommand(String inputCode) {
        if (inputCode == null) return true;
        if (!hasEndCommand) return false;
        return "E".equals(inputCode);
    }

    // 選択した処理 を 実行
    protected abstract boolean runFunction(String inputCode);

    // 処理結果を 返す (これを追加した)
    protected boolean getResult() {
        return true;
    }
}

内容確認後 更新

class UpdateConfirm extends AbstractDispatcher {
    private Jinzai jinzai;
    private boolean result = false; // これを追加した

    public boolean run(BufferedReader reader, Jinzai jinzai) {
        this.jinzai = jinzai;
        return super.run(reader);
    }

    // 選択肢 を 表示
    public void beforeDisplayMenu() {
        System.out.print("\n以下の内容で更新します。");
        // 人材情報 表示
        JinzaiDetailView jinzaiDetailView = new JinzaiDetailView();
        jinzaiDetailView.display(jinzai);
        System.out.print(" [Y, N]>");
    }

    // 選択した処理 を 実行
    public boolean runFunction(String inputCode) {
        if (!inputCode.equals("Y")) {
            System.out.println();
            result = false; // "N" なら 「更新したい項目を選択してください」に戻る (これを追加した)
            return true;
        }

        // 人材更新 更新処理
        Repository<Jinzai> jinzaiRepository = new Repository<Jinzai>();
        jinzaiRepository.update("jinzai.txt", jinzai, Jinzai.class);

        System.out.println("更新しました。\n");
        result = true; // "Y" なら 「人材IDを入力」に 戻る (これを追加した)
        return true;
    }

    // 処理結果を 返す (これを追加した)
    @Override
    protected boolean getResult() {
        // "Y" なら 「人材IDを入力」に 戻る
        // "N" なら 「更新したい項目を選択してください」に戻る
        return result;
    }
}