きままに記録箱

フロントエンドたまに他のはなし

リーダブルコード学習メモ

転職先でリーダブルコードを読むことになり、とりあえず1周読破したときの学習メモ。

※15章は本書で出てきたコード作法を使った設計例の話だったので、記載していません

1章-理解しやすいコード-まとめ

  • コードは他の人が最短で理解できるように書く
  • コードは短いほうがいいが、上記を優先する

第1部-表面上の改善-

2章-名前に情報を詰め込む-まとめ

  • 明確な単語を選ぶ

    • 例えば「get」はどんなところから取るのか分かりづらい
    • 類語辞典を活用する
  • 汎用的な名前を避ける

    • 「tmp」や「foo」「retval」などは避ける
    • 変数の意味を表す単語を使う

    • ループ文に出てくる「i」「j」「k」はより明確な単語を使うとバグが目立ちやすい。 例)「i」→「club_i」/「ci」

  • 抽象的よりも具体的な言葉を選ぶ

  • 名前に情報を追加

    • 単位を表す変数には変数名に単位をつける
  • 名前の長さを決める

    • 変数名は1つの単語だけにする必要はない
    • テキストエディタの単語補完機能を活用
      • Intelli IDEA:Alt+/
  • 名前のフォーマットで情報を伝える

    • チームごとにクラス名は大文字から、変数名は小文字から始めるみたいなルールを設ける。

3章-誤解されない名前-まとめ

  • 限界値を含めるときはminとmaxを使う
  • 範囲(最初から最後の要素を含む)を指定するときはfirstとlastを使う
  • 包含/排他的範囲(最初を含むが、最後の要素は含まない)にはbeginとendを使う
  • ブール値の変数や関数にはis/has/can/shouldなどを用いる
  • 複数の名前を検討する
    • 名前を決める間に反対意見を考える
    • 最善の名前=誤解されない名前

4章-美しさ-まとめ

  • 見た目が美しいコードのほうが見やすい
  • 複数のコードブロックで同じようなことをしていたら、適切な改行を入れる(ズレている箇所が目立たないように)
  • コードの列を整列する
    • 空白を入れたりして位置調整する
  • ある場所でA・B・Cのように並んでいたものを、他の場所でB・C・Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る。
  • 空行を使ってコードを「段落」に分割する
    • コードをグループ別に分ける
    • 段落の始めに要約用のコメントをいれるのも可
  • 「正しい」スタイルよりも一貫性のあるスタイルのほうが大切

5章-コメントすべきことを知る-まとめ

  • コメントの目的は書き手の意図を読み手に知らせること
  • コメントすべきではないこと
    • コードからすぐわかること
    • ひどいコードを補う「補助的コメント」、コメントするのではなくコードを修正する
  • 記録すべき自分の考え
    • 映画の監督コメンタリーみたいに、なぜコードが他のやり方ではなくこうなっているかコメントする
    • コードの欠陥をTODO:やXXX:などの記法を使って示す
    • 定数の値にまつわる「背景」
  • 読み手の立場になって考える
    • (チームに参画したりなどで)コードを読んだ人が「えっ」と思うところを予想してコメントする
    • 平均的な読み手が驚くような動作は文書化しておく(ハマりそうな罠を告知する)
    • ファイルやクラスには「全体像」のコメントを書く
    • 読み手が細部に捕らわれないように、コードブロックにコメントをつけ概要をまとめる

6章-コメントは正確で簡潔に-まとめ

  • 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
  • 関数の動作はできるだけ正確に説明する
    • 実例を用いると尚良
  • コードの意図は詳細レベルではなく、高レベルで記述する
  • よくわからない引数にはインラインコメントを使う(例:Function(/* arg = */...)
    • C++Javaでは特に活用する
    • Pythonなら名前付き引数は可能(例:Function( arg = ...)
  • 多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ

7章-制御フローを読みやすくする-まとめ

  • 比較を書くときは、変化する値を左に、より安定した値を右に配置する
  • if/else文は一般的に肯定形・単純・目立つものを先に処理する
  • 三項演算子(?:)・do/whileループ・gotoなどは使わないほうがよい
  • 深いネストを避けるために「直線的」なコードが有効
    • 早めに返すことでネストを削除したりコードをクリーンできる
    • 関数内で複数のreturn文をしようしても問題ではない、早めに返り値を出すことができる
    • ネストが深いと読みづらくなる

8章-巨大な式を分割する-まとめ

  • 最も簡単な方法は「説明変数」の導入
    • 大きな式の値を保持する変数
  • ド・モルガンの法則を使って論理式をきれいにできる
    • 例)if (!(a && !b))if (!a || b)と同じ

9章-変数と読みやすさ-まとめ

  • 変数が多いと変数を追跡するのが難しい
  • 変数を削除する
    • 一度しか使っていない、中間結果を保持する変数は削除する
  • 変数のスコープを縮める
    • 変数のスコープが大きいとスコープを把握する時間が長くなる
    • 変数のことが見えるコード行数をできるだけ減らす
  • 一度だけ値が設定される変数を使う
    • constfinalを使う

10章-無関係の下位問題を抽出する-まとめ

  • プロジェクト固有のコードから汎用コードは分離させる
  • 汎用コードはたくさん作る
    • ただし小さい関数は作りすぎてコードが読みにくくならないようにする 

11章-一度に1つのことを-まとめ

  • コードは1つずつタスクを行うようにしなければいけない

12章-コードに思いを込める-まとめ

  • ロジックを明確に説明する
    • 簡単な言葉でロジックを説明する
    • できれば口で説明してみる→「ラバーダッキング
    • 問題や設計をうまく口で説明できないのであれば、なにかを見落としているか、詳細が明確になっていない

13章-短いコードを書く-まとめ

  • 不必要な機能をプロダクトから削除する。過剰な機能を持たせない
  • 最も簡単に問題を解決できるような要求を考える
  • 定期的にすべてのAPIを15分ほどかけて読む、標準ライブラリに慣れ親しんでおく
    • ライブラリでどんなことができそうなのか眺めておくことで、「そういえば、これAPIでみたような・・・」と思い出し、役に立つ場合がある

14章-テストと読みやすさ-まとめ

  • 他のプログラマが安心してテストの追加や変更ができるように、テストコードを読みやすくする
  • テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード1行で記述できるといい
  • テストが失敗したらバグの発見や修正がしやすいエラーメッセージを表示する
  • テストに有効な最も単純な入力値を使う
  • テスト関数に説明的な名前をつけて、何をテストしているのかを明らかにする。Test1()ではなくTest_<関数名>_<状況>のような名前にする。

11月から無事転職いたしました。 それ関連でゴタゴタしてたこともあり、なかなか投稿できず投稿するする詐欺なっていたので投稿します。本記事を機に投稿ペースを戻していけばなと思います。