読者です 読者をやめる 読者になる 読者になる

javaのenumを定数クラスだけに使わないでより良い使い方を学ぶ

enumは型安全な列挙定数が作れるこれですね。

public enum Sample {
    HOGE,
    FOO,
    BAR,
}

enum basics - しげるメモによるとenumってクラス本体にメソッド定義できるんですね。

public enum Sample {
    HOGE,
    FOO,
    BAR,
    ; // セミコロンで区切る
    public boolean isHoge() {
        return this == HOGE;
    }
}

この仕組みを使って「ステートパターンをenumで」

public class Lifecycle {
    
    // 初期状態はINITIALに固定
    private State state = State.INITIAL;
    
    // 外側に公開する状態遷移メソッド
    public void start() {
        state = state.start(this);
    }
    public void stop() {
        state = state.stop(this);
    }
    public void disopse() {
        state.stop(this);
        state = State.DISPOSED;
        // 破棄のための処理
    }
    
    // state == ACTIVATED のときのみ実行できる処理
    public void someMethod() {
        if (state != State.ACTIVATED) {
            throw new IllegalStateException();
        }
        // ...
    }
    
    // 外側に公開しない状態遷移のための処理
    void doInitialize() {
        // ...
    }
    void doActivate() {
        // ...
    }
    void doDeactivate() {
        // ...
    }
    
    // 状態オブジェクト
    private enum State {
        INITIAL {
            @Override public State start(Lifecycle outer) {
                outer.doInitialize();
                outer.doActivate();
                return ACTIVATED;
            }
            @Override public State stop(Lifecycle outer) {
                return INITIAL;
            }
        },
        ACTIVATED {
            @Override public State start(Lifecycle outer) {
                return ACTIVATED;
            }
            @Override public State stop(Lifecycle outer) {
                outer.doDeactivate();
                return DEACTIVATED;
            }
        },
        DEACTIVATED {
            @Override public State start(Lifecycle outer) {
                outer.doActivate();
                return ACTIVATED;
            }
            @Override public State stop(Lifecycle outer) {
                return DEACTIVATED;
            }
        },
        DISPOSED {
            @Override public State start(Lifecycle outer) {
                return DISPOSED;
            }
            @Override public State stop(Lifecycle outer) {
                return DISPOSED;
            }
        },
        ;
        public abstract State start(Lifecycle outer);
        public abstract State stop(Lifecycle outer);
    }
}

多態もenumで表現

public enum JobType {

    CLERK {
        @Override
        public int calculateBonus(int salary) {
            return salary;
        }
    },
    SALESMAN {
        @Override
        public int calculateBonus(int salary) {
            return salary * 2;
        }
    },
    MANAGER {
        @Override
        public int calculateBonus(int salary) {
            return salary * 3;
        }
    },
    ANALYST {
        @Override
        public int calculateBonus(int salary) {
            return salary * 4;
        }
    },
    PRESIDENT {
        @Override
        public int calculateBonus(int salary) {
            return salary * 5;
        }
    };

    public abstract int calculateBonus(int salary);
}


List<Employee> results =
    jdbcManager.from(Employee.class).getResultList();
int totalBonus = 0;
for (Employee e : results) {
    totalBonus += e.jobType.calculateBonus(e.salary);
}
System.out.println("Total Bonus:" + totalBonus);

これはステキ

enumって奥が深いのね。