LoginSignup
0
0

More than 3 years have passed since last update.

switchとEnumMap

Last updated at Posted at 2020-09-18

switch

switchはbyte、short、int型の値やString型の値だけでなく列挙型も式に取れるので、サクッと条件分岐させたいときには便利ですよね。

ただ、その主張が激しくなってくると・・・。

DayOfWeek列挙体
enum DayOfWeek {
    SUNDAY    ("日曜日"),
    MONDAY    ("月曜日"),
    TUESDAY   ("火曜日"),
    WEDNESDAY ("水曜日"),
    THURSDAY  ("木曜日"),
    FRIDAY    ("金曜日"),
    SATURDAY  ("土曜日");

    private String name;

    private DayOfWeek(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
};
Personクラス
class Person {
    private DayOfWeek dayOfWeek;
    private String lyrics;

    private Person(DayOfWeek dayOfWeek) {
        setDayOfWeek(dayOfWeek);
    }

    // インスタンスを生成するstaticメソッド
    static Person todayIs(DayOfWeek dayOfWeek) {
        return new Person(dayOfWeek).doSometing();
    }

    // 曜日を設定するメソッド
    Person setDayOfWeek(DayOfWeek dayOfWeek) {
        Objects.requireNonNull(dayOfWeek, "帰れや");
        this.dayOfWeek = dayOfWeek;
        return this;
    }

    // 何かするメソッド
    Person doSometing() {
        lyrics = dayOfWeek.getName();
        switch (dayOfWeek) {
            case SUNDAY:
                lyrics += "に市場へでかけ";
                break;
            case MONDAY:
                lyrics += "におふろをたいて";
                break;
            case TUESDAY:
                lyrics += "はおふろにはいり";
                break;
            case WEDNESDAY:
                lyrics += "にともだちが来て";
                break;
            case THURSDAY:
                lyrics += "は送っていった";
                break;
            case FRIDAY:
                lyrics += "は糸まきもせず";
                break;
            case SATURDAY:
                lyrics += "はおしゃべりばかり";
                break;
        }
        return this;
    }

    // ギャンブルをするメソッド
    Person gambling(int amount) {
        lyrics = dayOfWeek.getName();
        switch (dayOfWeek) {
            case SUNDAY:
            case TUESDAY:
            case THURSDAY:
            case FRIDAY:
            case SATURDAY:
                lyrics += "に" + amount + "万負けて";
                break;
            case MONDAY:
            case WEDNESDAY:
                lyrics += "に" + amount + "万勝って";
                break;
        }
        return this;
    }

    // テュリャるメソッド
    Person turya() {
        switch (dayOfWeek) {
            case SUNDAY:
                lyrics += "テュリャ";
                break;
            case MONDAY:
                lyrics += "テュリャ リャ";
                break;
            case TUESDAY:
                lyrics += "テュリャ テュリャ テュリャ";
                break;
            case WEDNESDAY:
                lyrics += "テュリャ テュリャ テュリャリャ";
                break;
            case THURSDAY:
                lyrics += "、あ?";
                break;
            case FRIDAY:
                lyrics += "てゆりや";
                break;
            case SATURDAY:
                lyrics += "turya";
                break;
            default:
                break;
        }
        return this;
    }

    // 歌うメソッド
    Person sing() {
        System.out.println(lyrics);
        lyrics = "";
        return this;
    }
}

このように、くどさがでてきます。
breakの記述漏れにより予期せぬフォールスルーを生む危険性もでてきます。

Personクラスの使用例
Person.todayIs(MONDAY).sing()
    .setDayOfWeek(TUESDAY).doSometing().turya().sing()
    .setDayOfWeek(THURSDAY).gambling(100).turya().sing()
    .setDayOfWeek(SATURDAY).doSometing().turya().sing();
出力
月曜日におふろをたいて
火曜日はおふろにはいりテュリャ テュリャ テュリャ
木曜日に100万負けて、あ?
土曜日はおしゃべりばかりturya

EnumMap

列挙体と紐付けてデータを管理できるEnumMapというものがあります。
これを使って書き換えると、

Personクラス(修正)
class Person {
    ... // フィールドから曜日を設定するメソッドまで省略

    // 何かするメソッド
    Person doSometing() {
        lyrics = dayOfWeek.getName() + SOMETHING_MAP.get(dayOfWeek);
        return this;
    }

    // ギャンブルをするメソッド
    Person gambling(int amount) {
        lyrics = dayOfWeek.getName() + "に" + amount + "万" + GAMBLING_MAP.get(dayOfWeek);
        return this;
    }

    // テュリャるメソッド
    Person turya() {
        lyrics += TURYA_MAP.get(dayOfWeek);
        return this;
    }

    // 歌うメソッド
    Person sing() {
        System.out.println(lyrics);
        lyrics = "";
        return this;
    }

    // EnumMap

    /** 何か */
    private static final EnumMap<DayOfWeek, String> SOMETHING_MAP =
        new EnumMap<>(DayOfWeek.class) {{
            put(SUNDAY, "に市場へでかけ");
            put(MONDAY, "におふろをたいて");
            put(TUESDAY, "はおふろにはいり");
            put(WEDNESDAY, "にともだちが来て");
            put(THURSDAY, "は送っていった");
            put(FRIDAY, "は糸まきもせず");
            put(SATURDAY, "はおしゃべりばかり");
        }};

    /** ギャンブル */
    private static final EnumMap<DayOfWeek, String> GAMBLING_MAP =
        new EnumMap<>(DayOfWeek.class) {{
            final String WIN = "勝って";
            final String LOSE = "負けて";
            put(SUNDAY, LOSE);
            put(MONDAY, WIN);
            put(TUESDAY, LOSE);
            put(WEDNESDAY, WIN);
            put(THURSDAY, LOSE);
            put(FRIDAY, LOSE);
            put(SATURDAY, LOSE);
        }};

    /** テュリャ */
    private static final EnumMap<DayOfWeek, String> TURYA_MAP =
        new EnumMap<>(DayOfWeek.class) {{
            put(SUNDAY, "テュリャ");
            put(MONDAY, "テュリャ リャ");
            put(TUESDAY, "テュリャ テュリャ テュリャ");
            put(WEDNESDAY, "テュリャ テュリャ テュリャリャ");
            put(THURSDAY, "、あ?");
            put(FRIDAY, "てゆりや");
            put(SATURDAY, "turya");
        }};
}

とりあえず管理はしやすくなった・・・はず。

いまいちコレ!という使いどころに自信がありませんが、列挙体と直接紐付けるデータならば列挙体内で直接定義し、そうでなければ個々のクラスでEnumMapを活用するというような使い方なのでしょうかね1


  1. 今回は後者を想定して(DayOfWeek列挙体を他クラスでも使い回すと仮定して)、列挙体には曜日の名前以外のデータを紐付けませんでした。 

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0