はじめに
いろんな方やいろんな記事で「リーダブルコードは名著だから読んだ方がいい」と言われてきましたが、何かと理由をつけて読むのを後回しにしていました(ただの怠惰多忙でしたので)
ただ最近まとまった時間があったので初めからじっくり読んでみました。多くの方がお薦めする理由がわかるほど綺麗なコードを書くためのエッセンスが詰まっていました。
当記事ではリーダブルコードをただ読んだ感想を書くのではなく、読んだあと私のコードがどのように変わったのかをお見せしたいと思います。
学んだ内容と改善例として実際に1年以上も前に書いたクソコード良い勉強教材を用いてリファクタリングしていきます。
当記事では、個人的に学びになった箇所を自分なりに要約し、
- 心構え
- 命名
-
コメント
と3つに章立てしてお話しさせていただきます。
心構え編
そもそも、なぜ綺麗なコードを書かなければならないのでしょうか?
確かにチーム開発をしている際は、コードは綺麗でリーダブル(理解しやすい)な方がいいと思います。属人性の高いコードを書いてしまうとチームメンバーにも負担になってしまいますし、開発効率を下げてしまいます。
では、個人開発の時はどうでしょうか?
「自分だけしか触らないし、他の人にも迷惑をかけないから自分だけコード内容が分かればいいや」そんなふうに私は読む前は思っていました。
ただ、本著では個人開発でも綺麗なコードを書くことの重要性を指摘しており、またこのように書かれています。
「他の人」というのは、自分のコードに身に覚えのない6ヶ月後の君自身かもしれない(p6)
確かにその通りだと思いました。特に今回、自分自身のコードをリファクタリングしたのですが「なぜこのように書いたのか、どのような処理なのか」を読解するのにかなり苦労しました...
この記事を執筆する際に改めて、たとえ自分しか読まなくても綺麗なコードを書くことの重要性が身に沁みました。
綺麗なコードを書くことは未来の自分のためにもなる
命名編
命名編では変数や関数にどのような名前をつけるのがいいのかについてまとめていきます。
ではどのような変数名や関数名をつけるのが良い名付けだと言えるのでしょうか?
この質問に対して、筆者はこのように述べています。
名前は短いコメントだと思えばいい、短くてもいい名前をつければ、それだけ多くの情報を伝えることができる。(p10)
では上記の原則に従って良い変数名を付けるためにはどうすれば良いでしょうか?
筆者は6つのTipsを与えてくれています。
- 明確な単語を選ぶこと
- 汎用的な名前を避ける
- 具体的な名前をつける
- 接頭辞、接尾辞をつけて情報を加える
- 名前の長さを決める
- 名前のフォーマットで情報を伝える
本編では何個かピックアップして紹介いたします。
明確な単語を選ぶ
明確な単語を選ぶとはどういうことでしょうか?まずは私のダメなコードを見てください
//====== 一部コード割愛 ===========
const getData = async(url)=>{
const data = await fetch(url).json()
return data
}
どうでしょうか?上記のコードは、きちんと動作しますし、これでも全然良いのですが、何をやっていて、どんな処理なのかが伝わりづらいですよね。。。
ではなぜ他の人が読みづらいコードになってしまっているのでしょうか?
それはget
という単語とData
という名前が抽象的すぎるからです。
例えばgetという単語だとどこから取ってくるのかが分かりません(db?キャッシュ?API?)
またData
も同じ何のデータなのかが変数からちっとも分かりません(ユーザ?商品?値段?...)
では下記のように書き換えたらどうでしょうか?
const fetchProducts = async(url)=>{
const products = await fetch(url).json()
return products
}
関数名をget
→fetch
data
→ products
と変えてみました。
どうでしょう、少し関数名を変えるだけでもかなり関数の処理が理解しやすくなったと思いませんか?
実はこのコード私がだいぶ前に楽天のAPIから商品情報を取ってきた際のコードの一部でした。
一部のコードの抜き出しだったので理解するのは難しかったと思いますが、関数名を改善しただけで上記の文脈がなくても何を行なっている関数かが伝わったと思います。
このようにより具体的に命名することにより、文脈がなくてもより多くの情報を他の人に伝えられたと思います。
具体的な単語や名前にすることで多くの情報を他の人に伝えることができる。
汎用的な名前を避ける
抽象的な名前を避けること以外にも気をつける点があります。それは汎用的な名前を避けることです。
ここでいう、汎用的な名前とはtemp
やit
などです。
正直、私自身あまり本著のダメな例として出てくる変数(temp
it
)をあまり使った覚えが無かったので、読んでいる時は得意げだったのですが、昔のコードを漁っていたらびっくり,至る所で使っていました。笑
特によく使ったのはtest
という変数名で個人的にはtemp
と同じように一時的に確認する用として、使っていたのですが、その後そのまま引き続き使ってしまっていました。。。
全く良くないですよね、よくないコードの例が下記の通りです。
const [test, setTest] = useState();
//============ 中略 ==================
<input onChange={updateText} value={test} placeholder="キーワードを入力してください"/>
これだとせっかくuseStateを用いて管理しているのに、変数からは何の状態を管理しているのかが全くわからないですよね
確かにtest
などの汎用的な変数名は便利ではありますが、それがかえって指すものが多く分かりづらくなってしまいます。
const [queryProducts, setQueryProducts] = useState();
//============ 中略 ==================
<input onChange={updateText} value={queryProducts} placeholder="キーワードを入力してください"/>
汎用的な名前を避けるだけで、一段とコードが分かりやすくなります。
汎用的なコードを使うことに関して筆者はこう述べています。
tmp・it・retvalのような汎用的な名前を使うときは、それ相応の理由を用意しよう(p15)
汎用的な名前を使うこと自体を否定しているわけではないですが、理由なくただの怠慢で用いること自体には気をつけるよう警鐘を鳴らしております。
汎用的な名前を用いる際は、明確な理由を持とう(そうでなければ怠慢)
終わりに
想像以上に長くなってしまったので、続きはまた今度書かせていただきたいと思います!
読んでいただきありがとうございました!