はじめに
オライリーの名著『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』(Dustin Boswell / Trevor Foucher 著)を一冊通読したので、全体を書評としてまとめます。
本書の核心はシンプルです。
コードは他の人が最短時間で理解できるように書く。
「動けばいい」でも「短ければいい」でもなく、読んで理解できるかどうかが判断基準です。「他の人」とは、6ヶ月後の自分自身も含みます。
本書は4部構成で、以下の15章+付録から成ります。
第I部 表面上の改善(1〜6章)
プログラムの変更やリファクタリングなしに「とりあえず」改善できる領域です。コードのすべての行に影響するため、最もコスパが高いとされています。
1章 わかりやすいコード
コードは短いほど良いですが、「短さ」は最優先ではありません。1行に詰め込んだ難読な式より、2行に分けた明快なコードのほうが優れているケースは多いです。コメントをつけてコードが長くなっても、理解が速くなるなら正解です。
2章 名前に情報を詰め込む
命名は短いコメントです。以下の指針が示されています。
-
明確な単語を選ぶ。
getより状況に応じてfetch/downloadを使う。Size()よりHeight()/NumNodes()など目的を明確にする -
tmp/retvalなどの汎用名を避ける。 一時変数として役割が明確なときだけtmpを使う -
抽象的な名前より具体的な名前。
ServerCanStart()よりCanListenOnPort() -
単位や属性を接尾辞・接頭辞で示す。
delay→delay_secs、password→plaintext_password - スコープが大きい変数には長い名前をつける。 逆に狭いスコープなら短くてもよい
3章 誤解されない名前
名前は「他の意味に取られないか?」という視点でチェックします。
- 範囲を示すなら
first/lastよりbegin/end(一般慣習に従う) - ブール値には
is/has/canなどのプレフィックスをつける -
getは軽量な処理を示唆するため、重い処理には使わない
4章 美しさ
一貫性のある整形は読みやすさに直結します。
- 似たコードは似た見た目にする(縦揃えなど)
- メソッドを「段落」のようにグループ分けし、空行で区切る
- コードの順序は重要度や依存関係に合わせる
5章 コメントすべきことを知る
コメントの目的は「コードの意図を伝えること」です。
書かないべきコメント
- コードを見ればわかること(冗長なコメント)
- ひどい名前の補足(名前を直す)
書くべきコメント
- 設計判断の理由(例:「ハッシュテーブルよりバイナリツリーが40%速かった」)
- コードの欠陥(
TODO:/FIXME:/HACK:) - 定数の「背景」(なぜその値にしたか)
// TODO: JPEGのみ対応。他フォーマットへの対応は後回し
fun loadImage(path: String): Bitmap { ... }
6章 コメントは正確で適切に
- 入出力の境界ケースをコメントで例示する
- 関数の動作ではなく意図をコメントする
- ファイル・クラスには「全体像」コメントをつける
第II部 ループとロジックの単純化(7〜9章)
制御フロー・論理式・変数の「精神的な荷物」を減らす章です。
7章 制御フローをわかりやすく読む
- 条件式は「左辺に変化する値、右辺に定数」と書く(
if (length >= 10)など) - ネストは浅くする。早期
returnでガード節を活用する -
do-whileは避ける
8章 巨大な式を分割する
理解できる「塊」の大きさには限界があります。
- 複雑な条件式は説明変数(
val isAdmin = ...)に切り出す - ド・モルガンの法則を使って論理式を読みやすくする
// Before
if (!(fileExists && !isReadonly)) { ... }
// After
val canWrite = fileExists && !isReadonly
if (!canWrite) { ... }
9章 変数と読みやすさ
- 「中間結果」変数を使って処理を分割する
- 変数のスコープをできる限り小さくする
- 変数は一度だけ書き込む(イミュータブルにできるならそうする)
第III部 コードの再構成(10〜13章)
コードを再構成する3つの方法を説明します。
10章 無関係下位問題を抽出する
本書で最も実践しやすく、効果が大きい技法の一つです。手順は明快です。
- 関数を見て「このコードの高レベルの目標は何か?」と自問する
- 各行に対して「高レベルの目標に直接効果があるか?」と問い直す
- 無関係な処理が多ければ、別関数に抽出する
例:最近傍探索の関数に球面距離計算が混入しているなら、spherical_distance() として切り出す。クッキー操作などの汚いインターフェースも get_cookie() / set_cookie() でラップする。
細かく分割しすぎると逆に読みにくくなります。「再利用できるか」「境界が明確か」を基準にしましょう。
11章 一度に1つのことを
コードは1つずつタスクをこなすように書きます。タスクが絡み合っているコードは、それぞれを別のコードブロックまたは別の関数に分離します。「オブジェクトが既存かを確認しながら作成しながらデータを挿入する」ような処理は分割が有効です。
12章 コードに思いを込めて
コードがわかりにくいと感じたら、まず自然言語で説明してみることを勧めています。説明の中に「こうあるべきだ」という設計が自然に現れる。それをそのままコードに落とし込むというアプローチです。
13章 短いコードを書く
最も読みやすいコードはコードがないことです。
- 不要な機能は実装しない(未使用コードを積極的に削除する)
- 問題を再定義してシンプルな解法を探す
- 標準ライブラリを熟知する(同じ処理を自前で書かない)
第IV部 選抜テーマ(14〜15章)
14章 テストと読みやすさ
テストコードも同じ原則で読みやすく書きます。
- テストコードは「他のコードを変更・バグ修正するときの自信」を支えるものです
- 入力・出力を1行にまとめた「コンパクトなテスト」を目指す
- テスト名には何をテストしているかを明確に書く(
test_<関数名>_<状況>) - 実装を支援する「テストしやすい設計」を意識する
15章 「分/時間カウンタ」を設計・実装する
最終章では実践的な設計例として、分・時間単位でイベント数を集計するカウンタの実装を通じ、これまでの技法が総合的に適用されています。重複コードの共有化・クラス分割・コメントの活用など、全章の集大成です。
全体を通した感想
本書が優れているのは、「読みやすいコードとは何か」という抽象論に留まらず、具体的なコードの before/after を豊富に示している点です。
特に印象に残ったのは次の3点です。
| ポイント | 一言まとめ |
|---|---|
| 命名 | 最もコスパの高い投資。変数名・関数名を変えるだけで読みやすさが劇的に変わる |
| コメント | 「意図」を書く。コードの動作説明は不要。なぜそうしたかを残す |
| 無関係下位問題の抽出 | 意識的にやらないと抜け落ちる。「このコードの目的は何か?」と問い直す習慣が必要 |
設計やアーキテクチャの前段として、コードの読みやすさの土台を作る本として、すべてのエンジニアにおすすめできます。