『リーダブルコード』を全然理解してないので、もう一度読んでみる


エンジニア界隈で評価の高い『リーダブルコード』。
この本を読む事によって、コードを読みやすくするテクニックや習慣をが身につくはず・・・だったのですが、レビューで指摘される事があり、うまく実践出来ていませんでした・・・
もう一度読んで内容をアウトプットすればもう少し身につくかなと思ったのでまとめます。

第I部 表面上の改善

1章 理解しやすいコード

優れたコードとは、理解しやすいコードである。この本で取り扱うテーマ。

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

  • 明確な単語を選ぶ
    def GetPage(url)という名前があるとする。
    この場合getの意味合いが広すぎるので、インターネットから取ってくるのであれば、FetchPage()やDownloadPage()の方が明確。

  • 汎用的な名前を避ける(あるいは、使う状況を選ぶ)
    tmp、retval、fooより値や目的を表した名前を選ぶべき。
    tmpを単に一時保存の変数として使うなど、場面によっては使用しても問題ない。

  • 抽象的な名前よりも具体的な名前を使う
    抽象的な名前を避け、具体的な機能を表す名前を使うべき。

  • 接尾辞や接頭辞を使って情報を追加する
    ミリ秒を表す場合に名前にmsを付け足したり、最大値を表す場合にmaxを付け足すとわかりやすくなる。

  • 名前の長さを決める
    スコープが小さければ短い名前でも良い。不必要に長い名前は避けるべき。
    チームのルールとして共有されて入れば、イニシャルを用いた省略系を使うのも良い。

  • 名前のフォーマットで情報を伝える
    アンダースコア・ダッシュ・大文字を使って情報を伝える。
    クラスのメンバ変数にアンダースコアをつけて、ローカル変数と区別するなど。

3章 誤解されない名前

  • 限界値や範囲を意識した名前にする。
    maxやmin、firstやlastなど。
  • 名前をつける時は複数の名前を検討する。

4章 美しさ

  • 一貫性のある簡潔な改行位置
  • 縦の線をまっすぐにする
    =の位置を揃えるなど

  • 似ているコードはコードのシルエットを同じようにする
    似ているコードは似ているようにみせる

  • 順番を揃える
    ある場所でA、B、Cのように並んでいたものをB、C、Aのように並べてはいけない。

  • 空行を使ってコードのまとまりごとに段落に分ける

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

読み手の立場になって考え、ハマりそうな罠を告知する

コメントすべきではないこと

  • コードからすぐ読み取れるできること。
  • ひどいコードを説明するコメント。コメントを書くのではなく修正する。

コメントすべきこと

  • なぜこのやり方になっているか
  • コードの欠陥をTODO:やXXX:などの記法を使って示す
  • 定数の値にまつわる背景

6章 コメントは正確で簡潔に

  • 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける。
  • コードの意図は、詳細レベルではなく、高レベルで記述する
  • 関数の動作を正確に記述する

第Ⅱ部 ループとロジックの単純化

7章 if/else ブロックの並び順

  • 条件は否定形よりも肯定系を使う。
  • 単純な条件を先に書く
  • 関心を引く条件や目立つ条件を先に書く
  • 条件は左が調査対象(値が変化する)で、右側が比較対象の方が読みやすい
# 良い例
i > 0

# 悪い例
0 < i
  • 関数から早く出す
    複数のreturn文を使ってはいけないと思っている人がいるが、関数から早く返すのはいいこと。

  • ネストを浅くする
    returnで早く返すかcontinue。

8章 巨大な式を分割する

  • 説明変数
    わかりにくいコードを説明する名前をつけた変数をつくり代入する。

例えば以下のようなコードを

if line.split(':')[0].strip() == "root":

usernameという変数に入れるだけで、usernameがrootの時の条件とわかりやすくなる。

username = line.split(':')[0].strip() if username == "root":
  • 要約変数

例えば以下のような条件式を

if (request.user.id == document.owner_id) { 

}

if (request.user.id != document.owner_id) {

}

以下のように変数に入れた方がコードがスッキリする。

final boolean user_owns_document = (request.user.id == document.owner_id);

if (user_owns_document) { 

}

if (user_owns_document) {

}

9章 変数と読みやすさ

  • 役に立たない一時変数を削除する
  • 変数のスコープを縮める
    変数のスコープを縮めるために大きなクラスを小さなクラスに分割することを考える
  • 変数を操作する場所が増えると現在値の判断が難しくなるので、一度だけ書き込むようにする

第Ⅲ部 コードの再編成

10章 無関係の問題を抽出する

  • 関数の目的を明確にし、目的と違う処理があった場合は別の関数に分ける
  • プロジェクト固有のコードから汎用コードを分離する

11章 一度に1つのことを

  • タスクを小さく分割し、別の関数に分ける

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

  • 自分よりも知識が少ない人が理解できるような「簡単な言葉」で説明する能力が大切
    問題や設計をうまく説明できないのであれば、何か見落としているか、詳細が明確になっていない。
    問題を声に出して説明するだけで解決策が見つかる。この技法は「ラバーダッキング」とも呼ばれている

13章 短いコードを書く

  • コードをできるだけ小さく軽量に維持する
    汎用的な「ユーティリティ」コードを作って、重複コードを削除する。
    未使用のコードや無用の機能を削除する
  • コードをできるだけ小さく軽量に維持する
  • 身近なライブラリに親しむ
    普段からAPIや組み込みモジュールを読んでおく。 新しいコードを書いている時に「これはAPIで見たような・・・」と思い出せれば新しい重複コードを書かなくて済む。

第Ⅳ部 選抜テーマ

14章 テストと読みやすさ

  • 大切ではない詳細はユーザーから隠し、大切な詳細は目立つようにする
  • テストを書くつもりでコードを書くと、テストしやすいようにコードを設計するようになる
  • テストに集中しすぎない
    テストのために本物のコードの読みやすさを犠牲にしてしまうことに気をつける。

15章「分/時間カウンタ」を設計・実装する

この章はC++を使った実践編なので割愛します。