ブログ記事
コードは人間のために書く:Robert C. Martin『Clean Code』の原則と論争
ソフトウェアのコードは、機械が実行する時間よりも、人間が読み、保守し続ける時間の方がはるかに長い。Robert C. Martin の『Clean Code』は、この前提に立って「他人が意図を正確に読み取れるコード」を書くための具体的な原則をまとめた一冊だ。一方で、その原則をどこまで適用すべきかをめぐっては明確な反論も存在する。賛否を知った上で使い分ける——それが本書との正しい付き合い方だ。
1. 意味のある名前で「メンタルマッピング」をなくす
本書が多くのページを割くのが命名だ。
読み手が変数名や関数名から「これは結局何を指すのか」を頭の中で別の言葉に翻訳しなければならない状態を、本書は「メンタルマッピング」と呼び、認知負荷とバグの温床だと指摘する。tmp や1文字の変数のような汎用的な名前を避け、発音でき、検索でき、役割が伝わる名前を付ける。一つの概念にはシステム全体で同じ単語を割り当て、型情報を名前に埋め込む古い記法は使わない。
名前そのものが仕様の説明になっていれば、読み手はコードの周辺を調べずに意図を理解できる。
2. 関数は小さく、一つのことだけをする
本書のもう一つの柱が関数設計だ。
巨大な関数はテストを難しくし、変更の影響範囲を広げる。本書は関数を小さく保ち、「一つのことだけを行う」単一責任を求める。さらに一つの関数の中では抽象レベルを揃え、「ビジネス上の判定」と「低レベルの文字列操作」を混在させないことで、処理が上から下へ物語のように読める構造を目指す。
引数は可能な限り減らし、状態を変える処理と値を返す処理を分ける「コマンド・照会分離」を守る。これにより、呼び出し側が予期しない副作用に悩まされにくくなる。
flowchart LR
subgraph NG["❌ 悪い例:巨大な関数"]
BF["processUserOrder()\n・ユーザー検証\n・在庫確認\n・価格計算\n・DB 書き込み\n・メール送信"]
end
subgraph OK["✅ 良い例:小さな関数の連鎖"]
F1["validateUser()"] --> F2["checkInventory()"]
F2 --> F3["calculatePrice()"]
F3 --> F4["saveOrder()"]
F4 --> F5["sendConfirmationEmail()"]
end
style NG fill:#fce8e8,stroke:#e53935
style OK fill:#e8f8e8,stroke:#4caf50
3. コメントは「なぜ」を語る
本書はコメントに対して禁欲的だ。
コードを見れば分かることをコメントで言い換えるのは二重管理を生む。さらにコメントはコード変更時に取り残されやすく、事実と食い違う「誤った情報」へと劣化するリスクを抱える。だからこそ、コメントを書く労力があるなら、まず名前や関数の構造を改善してコード自体に語らせるべきだ、と説く。
コメントが本当に必要なのは、コードに表れない「なぜ」——設計判断の意図、警告、非自明な前提——を残すときだ。
4. クリーンなコードの代償:パフォーマンスと教条主義への批判
本書の原則は「人間にとっての読みやすさ」を強く志向するが、実務に適用するうえでは反論も知っておきたい。
ゲームエンジン開発者の Casey Muratori は「Clean Code, Horrible Performance」と題した議論で、ポリモーフィズムや細かく分割されたオブジェクトがメモリ上に散在すると、現代のCPUのキャッシュ効率が落ち、実行速度を大きく損なう場合があると指摘した。高い性能が要求される領域では、データを連続したメモリに並べる「データ指向設計」の方が有利になりうる、という立場だ。
加えて、原則の適用が自己目的化する危険も指摘されている。「美しい構造を再現すること」が目的にすり替わり、まだ起きていない変更に備えた過剰な抽象化でコードを複雑にしてしまう、というパラドックスだ。本書の価値を認める読者の間でも、提示された原則を絶対視せず、自分が解くべき問題に照らして取捨選択する姿勢が必要だという見方は根強い。
5. どんなコードの詰まりに効くか
「リリース直後は問題なく動いていたのに、わずかな仕様変更のたびに予期しないバグが出て、コードの解読に時間を奪われる」——この詰まりに、本書の命名規則と単一責務の原則が効く。原因の多くは変数名や関数の粒度が設計されていないことにあり、名前と関数の構造を見直すことで、変更に強い構造へ近づける。
もう一つは、コードレビューの指摘がレビュアーの好みに依存し、チームの品質基準が揃わない状況だ。メンタルマッピングの排除やコマンド・照会分離といった原則を共通言語として持ち込むと、主観ではなく理由に基づいてレビューできるようになる。
6. 読む人を選ぶか
向いている人:
- 運用保守フェーズで、機能追加のたびにバグが出るコードに手を焼いているバックエンド開発者
- 基礎文法やデザインパターンは知っているが、クラスやメソッドをどこまで分割すべきか、エラー処理をどこに集約すべきかの判断基準を持たない中級プログラマ
- コードレビューの基準を言葉にして、属人的なレビューから脱却したいテックリード
向いていない人:
- プログラミングの基礎文法をこれから学ぶ人(本書は Java のケーススタディで具体的な設計判断を示すため、文法の土台が要る)
- 原則をそのまま全適用したい人(§4 で見たとおり、パフォーマンスが要求される領域では取捨選択が要る。「美しい構造の再現」自体が目的化する罠もある)
7. 次に開く本と、最初の一歩
本書で「良いコードの基準」を得たら、次の関心で進む先が分かれる。既存コードをその基準へ安全に近づける技術がほしいなら『リファクタリング』へ——コードの臭いを手がかりに、振る舞いを変えずに構造を改善する体系が得られる。変更を恐れずに書き続ける足場がほしいなら『テスト駆動開発』で、動くきれいなコードを小さいサイクルで育てる規律を身につける。関数・クラス単位の品質からシステム全体の依存の向きへ視野を広げたいなら『Clean Architecture』へ進む。
最初の一歩としては、次のコードレビューで名前について理由付きの指摘を1つしてみるのがよい。「なぜその名前が良いか」を言語化する練習——それが本書の原則を自分のものにする最短ルートだ。
筆者の体験から
レビューする立場になった頃、「この名前は分かりにくい」以上の言葉が出せず、レビュイーから具体的にどう直せばいいのか分からないと返されることが続いた。社内Wikiに命名ルールを並べても誰も見なくなり、根拠のある指摘の仕方を探して本書に行き着いた。読み終えてからは「メンタルマッピングが起きている」「抽象レベルが混ざっている」と原則名で伝えられるようになり、指摘に理由を一行添える習慣もついた。
ただし単一責任を意識しすぎて関数を割りすぎ、逆に「分けすぎでは」と指摘し返された時期もある。ある業務システムのユーザー更新処理で、コマンド・照会分離を提案して分割したところ7つの小さな関数に散らばり、別のメンバーから何をしているか追えないと言われて統合し直した。原則は守るものではなく、読みやすさのための道具だと割り切れたのは、この経験があったからだ。パフォーマンスとのトレードオフに関する批判は理屈として理解しつつも、業務システム中心の実務ではあまり実感が湧かなかった。
DevBookPath のマップで確認する
この本の前後の読書順は、DevBookPath のグラフで確認できます。
本記事のリンクには Amazon アソシエイト等の広告が含まれる場合があります。リンク経由の購入で運営者に紹介料が支払われることがあります。
この記事を共有
この地図を共有