Twitter (@eduraaa) や gist (ezura) でちょくちょくコードの考察のようなものを書いています。
今回はその中で、特に反応をいただいた、リファクタリング関係の Tips の一部を紹介します。
この記事のおすすめの読み方
- before の例を見て、その処理が何をしたいのか概要を読み取る
- after を見て before との印象の違いをみてみる
例 1
if /* condition */ {
label.text = "a"
} else if /* condition */ {
label.text = "b"
} else {
label.text = nil
}
label.text = {
if /* condition */ {
return "a"
} else if /* condition */ {
return "b"
} else {
return nil
}
}()
この処理の意味するところは「label.text の値を条件に応じて設定している」なのですが、before の場合、「何か条件分岐してるな」などの伝えたいことの本質とは少し外れたステップを読み手に"最初"に考えさせてしまいがちです。
「ぞれぞれの条件のとき、何がおきるのかな」→「なるほど。label.text の値を設定しているのだろう。いや、もしかして、label.text ではないものに対しての処理も紛れてないか?」→「紛れもなく、label.text の値を設定しているのだ」と、心配させてしまうかもしれません。
一方、after のようにすると、その処理群が何をしたいのか、その本質を一目見るだけでわかります。また、何か処理を付け足したとしても、本来の意図を大きく崩すような処理を書き難いです。
例 2
if /* condition */ {
labelA.text = "a"
labelB.text = "A"
labelC.text = "A"
} else if /* condition */ {
labelC.text = "B"
labelB.text = "B"
labelA.text = "b"
} else {
labelA.text = "c"
labelC.text = "C"
labelB.text = "C"
}
(labelA.text, labelB.text, labelC.text) = {
if /* condition */ {
return ("a", "b", "c")
} else if /* condition */ {
return ("b", "B", "B")
} else {
return ("c", "C", "C")
}
}()
(labelA.text, labelB.text, labelC.text) = {
if /* condition */ {
return (labelA: "a", labelB: "b", labelC: "c")
} else if /* condition */ {
return (labelA: "b", labelB: "B", labelC: "B")
} else {
return (labelA: "c", labelB: "C", labelC: "C")
}
}()
(labelA: labelA.text, labelB: labelB.text, labelC: labelC.text) = {
if /* condition */ {
return (labelA: "a", labelB: "b", labelC: "c")
} else if /* condition */ {
return (labelA: "b", labelB: "B", labelC: "B")
} else {
return (labelA: "c", labelB: "C", labelC: "C")
}
}()
before では、例 1 のときよりも更に全体を注意深く見なければ、正確に意図を掴みにくいのではないでしょうか。
パッと見て何をやりたいのか察しはつくと思うのですが、それでも、「それぞれの条件下の処理の中で labelA, B, C が全て揃っているのかどうか」不安になりそうです。
一方、after1, 2, 3 では、例 1 の after と同様に、意図がはっきりと読み取れます。書き足した場合も指定漏れの心配もありません。
after1, 2, 3 のどの記述が良いかは、好みと状況によりますが、返り値の tuple の要素にラベルをつけてあげると、それぞれの値が何なのか受取先の tuple を見に行かなくて良いので読む人に優しいと思います。ただ、冗長に感じる場合も多々あるので、使い分けていくことも必要です。
最後に
第一回はここまでにします。