リーダブルコード学習メモ
転職先でリーダブルコードを読むことになり、とりあえず1周読破したときの学習メモ。
※15章は本書で出てきたコード作法を使った設計例の話だったので、記載していません
1章-理解しやすいコード-まとめ
- コードは他の人が最短で理解できるように書く
- コードは短いほうがいいが、上記を優先する
第1部-表面上の改善-
2章-名前に情報を詰め込む-まとめ
明確な単語を選ぶ
- 例えば「get」はどんなところから取るのか分かりづらい
- 類語辞典を活用する
汎用的な名前を避ける
- 「tmp」や「foo」「retval」などは避ける
変数の意味を表す単語を使う
ループ文に出てくる「i」「j」「k」はより明確な単語を使うとバグが目立ちやすい。 例)「i」→「club_i」/「ci」
抽象的よりも具体的な言葉を選ぶ
名前に情報を追加
- 単位を表す変数には変数名に単位をつける
名前の長さを決める
- 変数名は1つの単語だけにする必要はない
- テキストエディタの単語補完機能を活用
- Intelli IDEA:
Alt
+/
- Intelli IDEA:
名前のフォーマットで情報を伝える
- チームごとにクラス名は大文字から、変数名は小文字から始めるみたいなルールを設ける。
3章-誤解されない名前-まとめ
- 限界値を含めるときはminとmaxを使う
- 範囲(最初から最後の要素を含む)を指定するときはfirstとlastを使う
- 包含/排他的範囲(最初を含むが、最後の要素は含まない)にはbeginとendを使う
- ブール値の変数や関数にはis/has/can/shouldなどを用いる
- 複数の名前を検討する
- 名前を決める間に反対意見を考える
- 最善の名前=誤解されない名前
4章-美しさ-まとめ
- 見た目が美しいコードのほうが見やすい
- 複数のコードブロックで同じようなことをしていたら、適切な改行を入れる(ズレている箇所が目立たないように)
- コードの列を整列する
- 空白を入れたりして位置調整する
- ある場所でA・B・Cのように並んでいたものを、他の場所でB・C・Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る。
- 空行を使ってコードを「段落」に分割する
- コードをグループ別に分ける
- 段落の始めに要約用のコメントをいれるのも可
- 「正しい」スタイルよりも一貫性のあるスタイルのほうが大切
5章-コメントすべきことを知る-まとめ
- コメントの目的は書き手の意図を読み手に知らせること
- コメントすべきではないこと
- コードからすぐわかること
- ひどいコードを補う「補助的コメント」、コメントするのではなくコードを修正する
- 記録すべき自分の考え
- 映画の監督コメンタリーみたいに、なぜコードが他のやり方ではなくこうなっているかコメントする
- コードの欠陥をTODO:やXXX:などの記法を使って示す
- 定数の値にまつわる「背景」
- 読み手の立場になって考える
- (チームに参画したりなどで)コードを読んだ人が「えっ」と思うところを予想してコメントする
- 平均的な読み手が驚くような動作は文書化しておく(ハマりそうな罠を告知する)
- ファイルやクラスには「全体像」のコメントを書く
- 読み手が細部に捕らわれないように、コードブロックにコメントをつけ概要をまとめる
6章-コメントは正確で簡潔に-まとめ
- 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
- 関数の動作はできるだけ正確に説明する
- 実例を用いると尚良
- コードの意図は詳細レベルではなく、高レベルで記述する
- よくわからない引数にはインラインコメントを使う(例:
Function(/* arg = */...)
) - 多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ
7章-制御フローを読みやすくする-まとめ
- 比較を書くときは、変化する値を左に、より安定した値を右に配置する
- if/else文は一般的に肯定形・単純・目立つものを先に処理する
- 三項演算子(?:)・do/whileループ・gotoなどは使わないほうがよい
- 深いネストを避けるために「直線的」なコードが有効
- 早めに返すことでネストを削除したりコードをクリーンできる
- 関数内で複数のreturn文をしようしても問題ではない、早めに返り値を出すことができる
- ネストが深いと読みづらくなる
8章-巨大な式を分割する-まとめ
- 最も簡単な方法は「説明変数」の導入
- 大きな式の値を保持する変数
- ド・モルガンの法則を使って論理式をきれいにできる
- 例)
if (!(a && !b))
はif (!a || b)
と同じ
- 例)
9章-変数と読みやすさ-まとめ
- 変数が多いと変数を追跡するのが難しい
- 変数を削除する
- 一度しか使っていない、中間結果を保持する変数は削除する
- 変数のスコープを縮める
- 変数のスコープが大きいとスコープを把握する時間が長くなる
- 変数のことが見えるコード行数をできるだけ減らす
- 一度だけ値が設定される変数を使う
const
やfinal
を使う
10章-無関係の下位問題を抽出する-まとめ
- プロジェクト固有のコードから汎用コードは分離させる
- 汎用コードはたくさん作る
- ただし小さい関数は作りすぎてコードが読みにくくならないようにする
11章-一度に1つのことを-まとめ
- コードは1つずつタスクを行うようにしなければいけない
12章-コードに思いを込める-まとめ
- ロジックを明確に説明する
- 簡単な言葉でロジックを説明する
- できれば口で説明してみる→「ラバーダッキング」
- 問題や設計をうまく口で説明できないのであれば、なにかを見落としているか、詳細が明確になっていない
13章-短いコードを書く-まとめ
- 不必要な機能をプロダクトから削除する。過剰な機能を持たせない
- 最も簡単に問題を解決できるような要求を考える
- 定期的にすべてのAPIを15分ほどかけて読む、標準ライブラリに慣れ親しんでおく
- ライブラリでどんなことができそうなのか眺めておくことで、「そういえば、これAPIでみたような・・・」と思い出し、役に立つ場合がある
14章-テストと読みやすさ-まとめ
- 他のプログラマが安心してテストの追加や変更ができるように、テストコードを読みやすくする
- テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード1行で記述できるといい
- テストが失敗したらバグの発見や修正がしやすいエラーメッセージを表示する
- テストに有効な最も単純な入力値を使う
- テスト関数に説明的な名前をつけて、何をテストしているのかを明らかにする。
Test1()
ではなくTest_<関数名>_<状況>
のような名前にする。
11月から無事転職いたしました。 それ関連でゴタゴタしてたこともあり、なかなか投稿できず投稿するする詐欺なっていたので投稿します。本記事を機に投稿ペースを戻していけばなと思います。