fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

覚えたてのJavaのenumを多用しすぎて変な実装になってた話

Javaenumクラスは次のような感じで実装をもてる。

enum ResultType {
  NONE, ONLY_ID, ALL;
  abstract Map<String, String> createResult(User data);
}

このままだとコンパイル通らないけど、例えばONLY_IDを次のようにすると

ONLY_ID(){
  @Override
  Map<String, String> createResult(User data){
    Map<String, String> res = new HashMap<>();
    res.put("user_id", data.getId());
    return res;
  }
}

switchで場合分けすることなく次のように書ける。

public String createJson(ResultType type){
  Map<String, String> map = type.createResult(this.user);
  // 残りは省略
}

ユーザが設定する値をenumクラスにマッピングして、それに固有の処理を上の様に実装するという感じ。 intの定数を定義するのよりよいし、設定値を追加/変更する際にペアになる実装を忘れずに済むので良いかなーと思って そんなコードを書いていたけど、Effective Java 第2版 を読んでて、
「ちょっと待って下さいそれってもしかしてタグ付けクラスでは?」ということに気づいたのでした。
そもそもswitch文を追い出すことしか考えてなかったのが間違ってた。

上の例だとResultType.createResult()(かそれに代わるメソッド)をファクトリメソッドにして
本筋の処理とかを個別のクラスに書いていけばよいのでしょうか。

よく考えてみたらResultTypeとかいうのよりもUserTypeにしてIDしかもたないSimpleUserクラスとか
全部の属性を持ってるFullUserクラスとかを返したほうが良さそう。

いいクラス設計ができるようになりたい。