int enumパターン
表現力が乏しい。
オレンジを期待しているメソッドにアップルを渡したり
アップルとオレンジを==演算子で比較してもコンパイラに怒られない。
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;
public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;
enumを使用した場合
public enum Apple {FUJI, PIPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}
値によって切り替えるenum型
以下のコードでは、技術的にはメソッドの終わりに到達可能であることや、
switchへ対応するcaseの追加を忘れるなどの問題点がある
public enum Operation {
PLUS, MINUS, TIMES, DIVID;
// 定数で表される算術操作を行う
public double apply(double x, double y) {
switch(this) {
case PLUS:
return x + y;
case MINUS :
return x - y;
case TIMES:
return x * y;
case DIVID:
return x / y;
}
throw new AssertionError("Unknown op" + this);
}
}
抽象メソッドを定義し、定数ごとに抽象メソッドをオーバーライドすることで問題点を改善することができる。
public enum Operation {
PLUS {
public double apply(double x, double y) {
return x + y;
}
},
MINUS {
public double apply(double x, double y) {
return x - y;
}
},
TIMES {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE {
public double apply(double x, double y) {
return x + y;
}
};
public abstract double apply(double x, double y);
}
ラムダを使用することでより簡潔にかける
public enum Operation {
PLUS((x, y) -> x + y),
MINNUS((x, y) -> x - y),
TIMES ((x, y) -> x * y),
DIVIDE ((x, y) -> x / y);
private final DoubleBinaryOperator op;
Operation (DoubleBinaryOperator op) {
this.op = op;
}
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
こちらを参考にさせていただきました。
Effective Java