📖
Readable Code Summary
内容
書籍『リーダブルコード』を読んだ時のメモ。
1章:理解しやすいコード
- 短いコードよりも直感的に「理解しやすいコード」を作る。
- 理解しやすいコードを作れば、設計やテストもやりやすくなる。
- パッとコードを見た時に「理解しやすいか?」を自問自答してみる。
2章:名前に情報を詰め込む
- いろいろな解釈ができるような変数名は避ける。
- 変数名に用いる単語が思いつかない時は、シソーラス(類語事典)で調べてみる。
- コードを作っている時はおろそかにしがちだが、
後から見た時に変数名は本当に大事な要素なので、
少し時間を取ってでも考える様にする。 - メソッドの動作をそのまま表しているようなメソッド名をつける。
- なるべくメソッド名を具体的にする。
- 値の単位や属性がわかる様な変数名にする。
start_time_ms # ミリ秒単位で値が格納されていることが分かる
raw_text # まだ何も処理を施していない状態のテキストが格納されていることが分かる
- 極力、省略形の変数名は使わない様にする。以下の
mm
のような名前は避けた方がいい。
mm = MessageManager.new
...
mm.get_message_from_db # mmってなんだった?となってしまう
message_manager = MessageManager.new
...
message_manager.get_message_from_db # こっちの方がいい
3章:誤解されない名前
- 誤解されるような名前は避ける。
例えば以下。これだけだと、解釈がいろいろできてしまう。- filter
- length
- limit
- 限界値を表すには、名前に max_ や min_ をつけるといい。
- 包含/排他的範囲を表すには、名前に begin と end をつけるといい。
- bool値の変数は、基本的に肯定形で定義したほうがいい。
bool disable_password = false;
bool use_password = true; // こっちの方がいい
4章:美しさ
- コードの見た目は綺麗に保つよう意識する。
- 適切な位置で改行を入れて読みやすくする。
- 複雑な式が続くようなロジックは、ヘルパー関数で置き換えてみる。
- メソッドのパラメータには、キーワード引数を使って理解しやすくする。
- 似たカテゴリに分類されるメソッド群は、1箇所にまとめて記述する。
- コードは段落ごとに分割して記述する。
- 各段落が1つのタスクになるので、メソッド分離もしやすくなる。
5章:コメントすべきことを知る
- コードを読めばすぐ分かるような情報を「コメント」として残す必要は基本的にない。
- 『優れたコード > ひどいコード + 優れたコメント』
- 以下のように、コメントとしてTODOを残すのは良い。
# TODO: XXXXXXX
...
- 定数などの値が、なぜその値なのかの背景理由をコメントとして残すのは良い。
- ユーザに公開するメソッドは、制約 や 限界 についてコメントを残すと良い。
- 短い表現の文章でいいので、複雑なロジックの全体像を要約した説明をコメントするのは良い。
(高レベルでの説明を加える)
6章:コメントは正確で簡潔に
- コメントには、曖昧な代名詞は避ける。
- メソッドの入出力の実例をコメントとして示す。
(ただし、誤解されないように実例は慎重に設定する)
7章:制御フローを読みやすくする
- 条件式では、「調査対象の値」を左側に、「比較対象の値」を右側に置くのが読みやすい。
- 条件は否定形よりも肯定形を使う。
- 関心の高い条件式を優先的に書く。
- 三項演算子は簡潔になるが、基本的には
if-else
で十分。 - 関数から早く抜け出すためのガード節を使う。
bool haveAccount(int user_id)
{
// 「ガード節」の例
if(user_id == null) return false;
...
}
- ネストが深い場合は、早めにガード節を使って処理できないか考えてみる。
- スレッドやシグナル/割り込みハンドラ、関数ポインタや仮想メソッドは、
使いすぎるとコードを追いずらくなってしまうということを意識して実装する。
8章:巨大な式を分割する
- 複雑な式の意味を名前で示す説明変数を定義する。
- 変数が多く使われている式に関しては、その式自体を要約変数として新しい変数に代入し、
その要約変数を使ってコードを作る。(要約変数に適切な名前を付ければ読みやすくなる) - 同じ式(しかも複雑)が何度も出てくる場合、その式も要約変数に代入してあげると良い。
- 巨大なコードロジックがあっても、それをヘルパー関数で置き換えてあげる。
9章:変数と読みやすさ
- 変数のスコープを見定め、出来るだけ必要となるスコープ内で変数を定義する。
こうすることで、スコープを過ぎたらその変数のことは考えなくてよくなる。 - 最初に全ての変数を定義しておく必要はなく、必要となったタイミングで定義してあげる。
こうすることで、その変数が現れるまでその変数を意識しなくてよくなる。 -
const
やfinal
を使って、一度だけしか変更されない変数だと明示的に示す。
10章:無関係の下位問題を抽出する
- エンジニアリング
- 大きなタスクを小さなタスクに分解し、それぞれの解決策を組み立てること
- 将来的に再利用可能な汎用的な関数を作成する。
- 完全に自己完結したコード
- 汎用コードをたくさん作って、独立したライブラリにできないか考えてみる。
- インタフェースの汚いコードは、自分でラッパー関数を作ってわかりやすくしてみる。
- プロジェクト固有コードから、汎用コードを分離する。
11章:一度に1つのことを
- 大きな関数は、小さな関数に分割できる。
- 関数の中でも、論理的な区分に分けてあげる。
- コードが行うべき 「タスク」を列挙すること から始めてみる。
12章:コードに思いを込める
- 他者に説明しやすいコードを作る。
- ロジックを作成する前に、 目の前のロジックをシンプルに 考えてみる。
- 簡単な言葉 で説明できるかを意識する(自問自答してみる)。
13章:短いコードを書く
- 今必要でない機能の実装に悩まなくていい。過剰な機能は不要。
- 必要になったときに考えれば良い。
- 今学んでいるプログラミング言語の 標準ライブラリ について調べてみる。
「動画学習サイト」とか「便利なライブラリまとめ記事」とかおすすめ。- 標準ライブラリにより、コードをシンプルかつ短くできる。
14章:テストと読みやすさ
- テストの本質は、以下に要約できる。
- 「ある状況」と「ある入力」から、「ある振る舞い」と「ある出力」を期待する。
- ヘルパー関数を使って、テストコードをシンプルに保つ。
- 1つの機能に複数のテストケースを用意する。(エッジケースなど)
さらに、本書p194-195
の表は非常に有用。
15章:「分/時間カウンタ」を設計・実装する
- メモリを無限に使ってしまう可能性のあるアプリになっていないか確認する。
Discussion