リーダブルコードとは
より良いコードを書くためのシンプルで実践的なテクニックが詰まった技術書。
コードは理解しやすくなければいけない というのが中心的な考え。
リーダブルコード感想
初心者にとってIT業界での基準のコーディングルールを知ることが出来る。
実務経験が浅い人には概要を掴む用に、
実務経験が少し付いてきたら、実務をより深めるための良書でした。
1部 表面上の改善
1章 理解しやすいコード
- コードは理解しやすくなければならない
- コードは他の人が最短時間で理解できるように書かなければいけない
##2章 名前に情報を詰め込む
-
明確な単語を選ぶ
例えば、Getではなく、状況に応じてFetchやDownloadなどを使う -
tmpやretvalなどの汎用的な名前を避ける
汎用的な名前を使うときは、それ相応の理由を用意している場合のみ -
抽象的な名前よりも具体的な名前を使う
ServerCanStart()
よりもCanListenOnPort()
の方が明確 -
名前に情報を追加する
大切な情報があれば、「単語」を変数に追加する
(例) 値の単位
時間やバイト数のように計測できるものであれば、変数名に単位を入れる
例えば、ミリ秒を表す変数名には、後ろに_ms
をつける。
- 名前の長さを決める
- スコープ(その名前が「見える」コードの行数)が小さければ短い名前でもいい
- 長い名前を入力するのは問題じゃない
- 頭文字と省略形:一般的な用語は使っていいが、プロジェクト固有の省略形は使わない
- 不要な単語を投げ捨てる
-
名前のフォーマットで情報を伝える
アンダースコア・ダッシュ・大文字を使って、名前に情報を詰め込むこともできる。
例えば、クラスのメンバ変数にアンダースコアをつけて、ローカル変数と区別する。
3章 誤解されない名前
名前が「他の意味と間違えられることはないだろうか?」と何度も自問自答する
-
限界値を含めるときは、名前の前に
max_
やmin_
を使う -
範囲を指定するときはfirstとlastを使う
-
包有/排他的にはbeginとendを使う
-
ユーザーの期待に合わせる
-
複数の名前を検討する
4章 美しさ
- 余白・配置・順序
- 読み手が慣れているパターンと一貫性のあるレイアウトを使う
- 似ているコードは似ているように見せる
- 関連するコードをまとめてブロックにする
-
一貫性のある簡潔な改行位置
-
縦の線をまっすぐにする
-
コードを「段落」に分割する
- 複数のコードブロックで同じようなことをしていたら、シルエットも同じようなものにする
- コードの「列」を整列すれば、概要が把握しやすくなる
- ある場所でA,B,Cのように並んでいたものを、他の場所でもB,C,Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る。
- 空行を使って大きなブロックを論理的な「段落」に分ける
5章 コメントすべきことを知る
コメントの目的は、書き手の意図を読み手に知らせること
コメントするべきではないこと
- コードからすぐにわかることをコードに書かない。
- ひどいコード(例えば、ひどい名前の関数)を補う「補助的なコメント」。コメントを書くのではなく、コードを修正する。
コメントすべきこと
- 記録すべき自分の考え
-
なぜコードが他のやり方ではなくこうなっているのか
-
コードの欠陥にコメントをつける (TODO:後で手を付ける / FIXME:既知の不具合があるコード)
-
定数の値にまつわる「背景」
-
読み手の立場になって考える
- 質問されそうなことを予想してコメントをつける
- 平均的な読み手が驚くような動作は文書化しておく
- ファイルやクラスには「全体像」のコメントを書く
- 読み手が細部に捉われないように、コードブロックにコメントをつけて概要をまとめる
6章 コメントは正確で簡潔に
- 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
- 関数の動作はできるだけ正確に説明する
- コメントに含める入出力の実例を慎重に選ぶ
- よく分からない引数にはインラインコメントを使う
- 多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ
2部 ループとロジックの単純化
7章 制御フローを読みやすくする
条件やループなどの制御フローはできるだけ「自然」にする。コードの読み手が立ち止まったり読み返したりしないように書く。
- 条件式の引数の並び順
左側:「調査対象」の式。変化する。
右側:「比較対象」の式。あまり変化しない。
(例) if(10 <= length)
でなく、if(length >= 10)
と書く
-
if/else のブロックの並び順
-
条件は否定形よりも肯定形を使う。
-
単純な条件を先に書く
-
関心を引く条件や目立つ条件を先に書く
-
三項演算子やdo/whileループは出来るだけ避ける
-
関数から早く返す
-
ネストを浅くする
- 早めに返してネストを削除する
- ループ内部のネストを削除する
8章 巨大な式を分割する
- 説明変数を使う
- 巨大な式を分割できる
- 簡潔な名前で式を説明することで、コードを文書化できる
- コードの主要な「概念」を読み手が認識しやすくなる
下記ではなく、
if line.split(':')[0].strip() == "root";
...
下記のように、説明変数を理由する
username = line.split(':')[0].strip()
if username == "root";
...
-
要約変数
-
巨大な文を分割する
9章 変数と読みやすさ
変数を適当に使うとプログラムが理解しにくくなることがある
(理由)
- 変数が多いと変数を追跡するのが難しくなる
- 変数のスコープが大きいとスコープを把握する時間が長くなる
- 変数が頻繁に変更されると現在の値を理解するのが難しくなる
プログラムの変数はすぐに増えるので、いずれ追跡できなくなる。変数を減らして、できるだけ「軽量」にすれば、コードは読みやすくなる。
-
変数を削除する
-
変数のスコープを縮める
変数のことが見えるコード行数をできるだけ減らす -
変数は一度だけ書き込む
変数に一度だけ値を設定すれば、コードが理解しやすくなる
3部 コードの再構成
##10章 無関係の下位問題を抽出する
- 関数やコードブロックをみて「このコードの高レベルの目標は何か?」と自問する
- コードの各行に対して「高レベルの目標に直接的に効果があるのか?あるいは、無関係の下位問題を解決しているのか?」と自問する
- 無関係の下位問題を解決しているコードが相当量あれば、それらを抽出して別の関数にする
→ プロジェクト固有のコードから汎用コードを分離する
11章 一度に1つのことを
コードは1つずつタスクを行うようにしなければいけない
読みにくいコードがあれば、そこで行われているタスクを全て列挙する。そこには別の関数(やクラス)に分割できるタスクがある。それ以外は、関数の論理的な「段落」になる。タスクをどのように分割するかよりも、分割するということが大切。
12章 コードに思いを込める
コードをより明確にする手順
- コードの動作を簡単な言葉で同僚にもわかるように説明する
- その説明のなかで使っているキーワードやフレーズに注目する
- その説明に合わせてコードを書く
13章 短いコードを書く
新しいコードは、テストや文書や捕手が必要になる。また、コードが増えると「重く」なるし、開発も難しくなる。
新しいコードを書かないようにするには、
- 不必要な機能をプロダクトから削除する。過剰な機能は持たせない。
- 最も簡単に問題を解決できるような要求を考える。
- 定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しんでおく