条件分岐がやばい。if文に塗れたソースコードになりそうで死ぬ。
そもそもこんなの仕様がおかしいんじゃないの?となるけど、どうしてもこの仕様が良いって時に少しでもIf文を減らした話。
(ruby2.3.1で開発してるよ。)
今回やりたいこと
- 以下の条件の組み合わせで表示するメッセージを変えたい。
- 対象グループかどうか(spike or jet)
- 対象商品かどうか(milk or coffee )
- 対象ユーザーかどうか(owner or user)
- 対象ステータスかどうか(hoge or fuga)
# if文で分岐するとこんな感じに全パターン網羅の地獄
if spike && coffee && owner && fuga
puts "サシスセソ"
elsif spike && milk && owner && fuga
puts "カキクケコ"
elsif jet && coffie && user && hoge
puts "アイウエオ"
~
~
~
end
そこで、少しでも地獄から抜け出すために、考えたのが、次の通り。
ポイントは多次元ハッシュを使うってところ。
# 1_条件と出力メッセージを組み合わせたハッシュを作っておく。
SELECT_MESSAGE =
{spike: {
milk: {
owner:{
hoge: "アイウエオ",
fuga: "カキクケコ"
},
user:{
hoge: "サシスセソ"
fuga: "アイウエオ"
}
},
coffee: {
owner:{
hoge: "アイウエオ",
fuga: "サシスセソ"
},
user:{
hoge: "タチツテト"
fuga: "カキクケコ"
}
},
jet:{
~~~~~~
}
# 2_各々の条件判断して、検索キー用のハッシュに格納しておく(条件分岐はここだけ)
def condition
parameters = {}
spike? ? parameters[:spike_or_jet] = "spike" : parameters[:spike_or_jet] = "jet"
milk? ? parameters[:milk_or_coffee] = "milk" : parameters[:milk_or_coffee] = "coffee"
owner? ? parameters[:owner_or_user] = "owner" : parameters[:owner_or_user] = "user"
hoge? ? parameters[:hoge_or_fuga] = "hoge" : parameters[:hoge_or_fuga] = "fuga"
parameters
end
# 3_で、あとは最初に作ったハッシュから検索用のハッシュを使って目的のメッセージを取り出せばオーケー。
def select_message
parameters = condition
# Hash#digメソッドでハッシュの最下層にあるメッセージを一発でとる。
message = SELECT_MESSAGE.dig(parameters[:spike_or_jet], parameters[:milk_or_coffee], parameters[:owner_or_user], parameters[:hoge_or_fuga])
puts message
end
コード量は増えるけど、これでif文の地獄から抜け出せるし、条件が変わったときでも対応しやすい。
他にも良いやり方(複雑な条件分岐に対するTIPS)があれば教えて欲しいです。