はじめに
リーダブルコードを読んで、アウトプット用として書いています。
何か間違いがありましたらコメントでお願いいたします。
1章 理解しやすいコード
コードを書く上で最も大切な原則は、
- コードは理解しやすくなければならない
- コードは他の人が最短時間で理解できるように書かなければいけない
コードを短く簡潔に書くことは大切だが、他の人が読んだ時にコードの理解に時間がかかるようであれば意味がない。
例えばif文を短く書ける三項演算子を使用すれば、コード自体は短くできるが、見る人によっては理解しづらいコードになってしまう可能性がある。
コメントをつけることでコードは長くなるがそのほうが理解しやすくなることもある。
あくまでもコードは短くしたほうがいいが、たとえコードが長くなっても理解するまでにかかる時間を短くするほうが優先度が高い。
2章 名前に情報を詰め込む
変数や関数、クラスなどの名前は短いコメントのようなもので、できるだけ多くの情報を詰め込む。
明確な単語を選ぶ
名前に情報を詰め込むには、空虚な単語は避け、明確な単語を選ぶ必要がある。
例えば「getPage」という名前の関数を作成した場合、何か情報を取得してくるという意味はなんとなく伝わってくる。
しかし、その情報はどこから取ってくるのかという疑問が生まれることになる。
具体的には、インターネットから取得してくるのであれば、「fetchPage」や「downloadPage」の方が直感的にも理解しやすい名前になる。
このように名前を考える時には、気取った言い回しよりも明確で正確になるように意識することが大切。
汎用的な名前は避ける
tmp・retval・fooのような汎用的な名前は避ける。値や目的を表した名前にする。
汎用的な名前を避けることで、バグを発見しやすくなる。
もう一つ意識することとして、生存期間が短く、一時的な保管であればこれらの単語は使用してもいい場合がある。
抽象的な名前よりも具体的な名前を使う
変数や関数などの構成要素の名前は、抽象的ではなく具体的なものにする。
例えば「serverCanStart」という名前の関数を作成したとする。内容としてはTCP/IPポートをサーバーがリッスンできるかを確認するというもの。
これでは抽象的なので、もっと具体的な名前にするのであれば「canListenOnPort」になる。この名前だと関数の動作を表しているので直感的に理解することもできる。
名前に情報を追加する
名前に情報を詰め込むのが大切だが、名前に詰め込める情報はあまり多くはない。
その情報は、変数や関数を見るたびに目に入ってくるので、どうしても伝えなければいけない情報は「単語」を名前に追加すれば良い。
名前に情報が少ない変数
var start = (new.Date()).getTime()
console.log(`開始時間は${start}秒`)
このコードは一見間違っていないように見えるが、 「getTime」はミリ秒を返すのに秒と記述ミスをしてしまっている。
このようなミスが起こらないように、「start_ms」といった名前に変更することで意味が明確になる。
名前の長さを決める
名前を決める時には、長い名前を避けるという暗黙的な制約がある。長い名前は覚えにくい、読みにくい、何より理解しづらい。
しかし、長い名前を避け続けると1つだけの単語の名前になってしまう。これもまた理解しずらい名前になってしまう。
スコープが小さければ短い名前でもいい
ここでいうスコープとは、その名前が見える行数のこと。
スコープが小さいと、全ての情報が見えるので、変数の名前は短くて良い。
2章のまとめ
- 明確な単語を選ぶ。GetではなくFetchやDownloadなど明確なものを使う
- tmpなどの汎用的な名前は避ける
- 具体的な名前を使って詳細に説明する。
- 名前に情報を追加する。startではなくstart_msなど単位をつける
- スコープ範囲によって命名する名前の長さを変える
とにかく大事なことは、名前に情報を詰め込み、名前を見ただけで理解することができること。
3章 誤解されない名前
誤解されない名前をつけるためには、他の意味と間違えられることはないだろうかという考えが重要になってくる。
限界値を決めるときはminとmaxを使用する
限界値が不明な名前
const items_in_cart_limit = 10
この変数の問題は、limitという単語は、未満なのか以下なのかがわからないということ。
そこで、max_items_in_cartという名前にすれば、コードの意味がより明確になる。
ブール値の名前
ブール値の変数やブール値を返す関数の名前を選ぶときは、trueとfalseの意味を明確にしなければならない。
アンチパターン
const read_password
この変数には2つの問題点がある。
- これからパスワードを読み取る
- 既にパスワードを読み取っている
この問題を解決するために、readは避けるべき。代わりに、needやuser_is_authenticatedを使用した方が良い。
ブーリアン型(true・false)を変数として命名する時は頭文字としてisやhasなどを使うのが良い。
3章 まとめ
良い名前とは、誤解されない名前である。コードを読んでいる人が、意図を正しく理解できるということ。
limitやlengthなどのように意味が曖昧な単語も多い。
そこで、名前を決める前に反対意見を考えることで、誤解されない名前かどうかを想像してみることが大切。
- 限界値はlimtではなく、max・minを使う
- ブーリアン型の命名ではisやhasなどを使う
4章 美しさ
優れたコードは、目に優しいものでなければならない。
3つの原則
- 一貫性のあるレイアウト
- 似ているコードは似ているように見せる
- 関連するコードはまとめてブロックにする
5章 コメントすべきことを知る
コメントの目的は、書き手の意図を読み手に知らせることである。
実際にコードを書いている本人は当たり前ながら、そのコードの意味は理解している。
しかし、知らない誰かがそのコードを読むときは、そのコードの意味は失われてしまう。
コメントするべきでは「ない」こと
コメントを読むとその分だけコードを読む時間は長くなる。
それに、コードも長くなり画面を占領してしまう。
なので、コメントにはそれだけの価値を持たせる必要がある。
重要になる考えが、コードからすぐわかることはコメントに書かないこと。
酷い名前はコメントをつけずに名前を変える
コメントとは、酷い名前の埋め合わせに使うべきではない。
特に関数名などはいろんなところで使用されるので、優れたコメントよりも名前が大切になる。
自分の考えを記録する
優れたコメントというのは、考えを記録するためのもの。
コードを書いている時の考えをコメントに反映させる。
下記のようにコードの状態を認め自分の考えを記録するのが良い
// このクラスは汚くなってきている
// サブクラスを作成し、整理した方が良い
class xxx {
// 処理
}
このコードは、コードが汚いことを認めて誰かに修正を促している。
コメントがなければ、コードが汚くて誰も近づかない。
コードの欠陥にコメントをつける
コードというのはその過程で欠陥を生む運命にある。
その欠陥をコメントとして残すことは恥ずかしいことではなく重要なこと。
改善が必要なコードはTODOを残す
// TODO: もっと高速なアルゴリズムを使う
このようなコメント記法はいくつか存在する。
記法 | 典型的な意味 |
---|---|
TODO: | あとで手をつける |
FIXME: | 既知の不具合があるコード |
HACK: | あまり綺麗じゃない解決策 |
XXX: | 危険!大きな問題がある |
大切なのは、これからコードをどうしたいのかを自由にコメントを書くこと。
そういうコメントを書くことで、コードの品質や状態を知らせたり、さらには改善の方向を示すことだってできる。
定数にコメントをつける
定数を定義するときには、その定数が何をするのか、なぜその値を持っているのかという理由が存在する。
しかし、名前が明確なものはコメントが必要ない定数も存在する。
コメントをつけることで改善できる定数も多いので、頭の中で考えていたことをコメントすることが重要。
読み手の立場になって考える
コード量が長い場合、途中でコードの理解が追いつかなくなってしまうことがある。
そのため処理の最初に要約コメントを残して読む人の理解を手助けする。
コードの全体像を理解してもらうことは非常に重要。
5章 まとめ
- コードから推測できるものはコメントすべきではない
- コメントのためのコメントはすべきではない
- 酷いコードを補うコメントを書くのではなく、コードを修正する
- コードを読んだ人が疑問に思うであろうコードにコメントを書く
- ファイルやクラスには全体像のコメントを書く
6章 コメントは正確で簡潔に
コメントを書くのであれば正確でなくてはならない。
また、コメントには画面の領域も取られるし、読むのに時間もかかる。
したがってコメントは簡潔でなければならない。
重要になる考えがコメントは領域に対する比率が高くなければならないこと。
6章 まとめ
- 曖昧な代名詞は避ける。これやあれ、それなど
- 関数の動作を正確に記述する