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?
-
今回は後者を想定して(DayOfWeek列挙体を他クラスでも使い回すと仮定して)、列挙体には曜日の名前以外のデータを紐付けませんでした。 ↩