Published
- 17 min read
[読書録]リーダブルコード
![img of [読書録]リーダブルコード](/_astro/2023-12-30-1.s-SMZpRW.png)
読んだ本
リーダブルコード(2012/6/23発売, 260ページ)
感想サマリ
社内で会話していると、コードを書く際に何度かこの本の話題をすることが多いので、備忘録として読書録を残しておく。
for文の書き方とか、コメントの書き方とか、社内でコードレビューされる際によく指摘される内容は、この本に関連することが多い。
他の方が書かれている感想にもあったが、コードを書き始めた最初は実感できないが、実際にプログラムを書いて運用してみて、改めて本書を読み直すと改めて実感できる内容があると思うので、手元に置いておいて、定期的に読み返すのが良さそう。
「運用してみて」という文言で記述したが、何か大きなシステムを作るとか、正社員でプログラムを書くことだけじゃなく、個人で書いたコードを数ヶ月後に見返してみるという観点でも一つの運用と言えるので、そういう経験から積んでいくのがよさそう。
また、本文中に達人プログラマーで紹介されているラバーダッキングについての話題にも触れられているので、本書からさらに他の良書と呼ばれる本を読むきっかけとして、経験が浅めのソフトウェアエンジニアに紹介するにはやはり良い本だと思う。
本書の関連リンク
内容メモ
1章 理解しやすいコードコードは理解しやすくなければならないコードは他の人が最短時間で理解できるように書かねばいけない「他の人」というのは、自分のコードに見覚えのない6ヶ月後の「君自身」かもしれない
2章 名前に情報を詰め込む明確な単語を選ぶtmpやretvalなどの汎用的な名前を避けるtmpという名前は、生存期間が短くて、一時的な保管が最も大切な変数にだけ使おう悪い例(user_infoのような名前が適している)良い例(tmpの生存期間が数行)具体的な名前を使って、物事を詳細に説明する変数名に大切な情報を追加する悪い例(ミリ秒に関する挙動が不明瞭)良い例(ミリ秒に関する挙動が明瞭)スコープの大きな変数には長い名前をつける大文字やアンダースコアなどに意味を含める
3章 誤解されない名前filterという名前は避けるべきだ。簡単に誤解を招いてしまう。「選択する」のであれば、select()にしたほうがよい。「除外する」のであれば、exclude()にしたほうがよい限界値を含めるときはminとmaxを使う範囲を指定するときはfirstとlastを使う包含/排他的範囲にはbeginとendを使うブール値の変数名は、頭にis,has,can,shouldなどをつけてわかりやすくすることが多い
4章 美しさ一貫性のあるスタイルは「正しい」スタイルよりも大切だある場所でA,B,Cのように並んでいたものを、他の場所でB,C,Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る
5章 コメントすべきことを知るコメントの目的は、書き手の意図を読み手に知らせることであるコードからすぐにわかることをコメントに書かない悪い例ひどい名前はコメントをつけずに名前を変える悪い例良い例「監督のコメンタリー」を入れるコードの欠陥にコメントをつける記法典型的な意味TODO:あとで手を付けるFIXME:既知の不具合があるコードHACK:あまりきれいではない解決策XXX:危険!大きな問題がある定数にコメントをつける良い例
6章 コメントは正確で簡潔に複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける。悪い例良い例関数の動作はできるだけ正確に説明する。コメントに含める入出力の実例を慎重に選ぶ。コードの意図は、詳細レベルではなく、高レベルで記述する。よくわからない引数にはインラインコメントを使う(例:Function(/_ arg = _/ ... ))。多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ。例)「正規化」「ヒューリスティック」「ブルートフォース」「ナイーブソリューション」
7章 制御フローを読みやすくする条件やループなどの制御フローはできるだけ「自然」にする良い例悪い例指針左側右側「調査対象」の式。変化する「比較対象」の式。あまり変化しない条件は否定形よりも肯定形を使う。例えば、 if (!debug) ではなく、 if (debug) を使う。単純な条件を先に書く関心を引く条件や目立つ条件を先に書く基本的にはif/elseを使おう。三項演算子はそれによって簡潔になるときにだけ使おうコードは上から下に読んでいくので、do/whileは少し不自然だ。コードを2回読むことなってしまう。whileループにすれば、コードブロックを読む前に繰り返しの条件がわかるので、読みやすくなるネストの深いコードは理解しにくいネストを削除するには「失敗ケース」をできるだけ早めに関数から返せばいい悪い例良い例
8章 巨大な式を分割する式を表す変数を使えば良い。この変数を説明変数と呼ぶこともある説明変数の例を説明変数を使えば、となる。大きなコードの塊を小さな名前に置き換えて、管理や把握を簡単にする変数のことを要約変数と呼ぶ要約変数の例のコードは、変数が5つも入っているから、考えるのにちょっと時間がかかる。このコードが言いたいのは、「ユーザーは文書を所持しているか?」なので、要約変数を追加すると、すると、この概念をもっと明確に表現できる。ドモルガンの法則を使う例「頭がいい」コードに気をつける。あとで他の人がコードをよむときにわかりにくくなる
9章 変数と読みやすさ役に立たない一時変数悪い例複雑な式を分割していないより明確になっていない。datetime.datetime.now()のままでも十分に明確だ一度しか使っていないので、重複コードの削除になっていない制御フロー変数を削除する悪い例良い例うまくプログラミングすれば、制御フロー変数は削除できる変数のことが見えるコード行数をできるだけ減らすグローバル変数に限らず、すべての変数の「スコープを縮める」のはいい考えだ悪い例}良い例JavaScriptでは、変数の定義にvarをつけないと、その変数はグローバルスコープに入ってしまう例JavaScriptの「ベストプラクティス」は、「変数を定義するときには常にvarキーワードをつける」C++やJavaのような言語にはブロックスコープがある。if/for/tryなどのブロックで定義された変数は、スコープがそのブロックに制限される変数を操作する場所が増えると、現在地の判断が難しくなる変数は一度だけ書き込む
10章 無関係の下位問題を抽出する与えられた地点から最も近い場所を見つける悪い例良い例関数を抽出することで、難しそうな幾何学の計算に心を奪われることなく、高レベルの目標に集中できるさらに言うと、spherical_distance()は個別にテストができる関数だプロジェクト固有のコードから汎用コードを分離する一般的な問題を解決するライブラリやヘルパー関数を作っていけば作っていけば、プログラムに固有の小さな核だけが残る小さな関数を作りすぎると、逆に読みにくくなってしまう
11章 一度に1つのことをブログに設置する投票用のウィジットの例(vote_changed)たった1つのこと(スコアを更新すること)をしているように見えて、実際には一度に2つのタスクを行っているので、別々のタスクを解決させる悪い例良い例読みにくいコードがあれば、そこで行われているタスクをすべて列挙する。そこには別の関数(やクラス)に分割できるタスクがあるだろう
12章 コードに思いを込めるコードをより明確にする簡単な手順コードの動作を簡単な言葉で同僚にもわかるように説明するその説明のなかで使っているキーワードやフレーズに注目するその説明に合わせてコードを書くある大学の計算機センターにはこんな方針があったプログラムのデバッグに悩む学生は、部屋の隅に置かれたテディベアに向かって最初に説明しなければいけないこの技法は「ラバーダッキング」とも呼ばれている
13章 短いコードを書くプログラマが学ぶべき最も大切な技能というのは、コードを書かないときを知ることなのかもしれないプロジェクトが成長しても、コードをできるだけ小さく軽量に維持する汎用的な「ユーティリティ」コードを作って、重複コードを削除する
1.未使用のコードや無用の機能を削除するプロジェクトをサブプロジェクトに分割するコードの「重量」を意識する。軽量で機敏にしておく新しいコードを書かないようにする不必要な機能をプロダクトから削除する。過剰な機能は持たせない最も簡単にあ問題を解決できるような要求を考える定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しんでおく
14章 テストと読みやすさ他のプログラマが安心してテストの追加や変更ができるように、テストコードを読みやすくする一般的な設計原則として、「大切ではない詳細はユーザから隠し、大切な詳細は目立つようにする」 べき8つの問題があるテストコード問題点このテストには、どうでもいいことがたくさん書かれている。テストステートメントはあまり長くしてはいけないテストが簡単に追加できない失敗メッセージが役に立たない。デバッグに使える情報が足りない一度にすべてのことをテストしようとしている。テストは分割したほうが読みやすいテストの入力値が単純ではない。-99998.7は「大音量」で目立つけど、これといって意味はないテストの入力値が不完全である。例えば、スコアが0の文書をテストしていない極端な入力値を使ってテストしていない。例えば、空のベクタ・巨大なベクタ・スコアが重複したものTest1()という意味のない名前がついている。テスト関数の名前は、テストする環境や状況を表したものにすべきテストに集中しすぎてしまう可能性 - テストのために本物のコードの読みやすさを犠牲にしてしまう - テストのカバレッジを100%にしないと気がすまない - テストがプロダクト開発の邪魔になる
15章 「分/時間カウンタ」を設計・実装する本物のプロダクトコードで使われているデータ構造「分/時間カウンタ」を見ていこう最初のバージョン問題点名前を改善するコメントを改善する15.2までのバージョン
付録高品質のコードを書くための書籍Code Completeリファクタリングプログラミング作法達人プログラマーClean Codeプログラミングに関する書籍JavaScript: The Good PartsEffective Javaオブジェクト指向における再利用のためのデザインパターン珠玉のプログラミングハイパフォーマンスWebサイトJoel on Software歴史的記録ライティングソリッドコードケント・ベックのSmalltalkベストプラクティス・パターンプログラム書法文芸的プログラミング
解説自然に読みやすいコードを書けるようになるための3つのステップ実際にやる当たり前にするコードで伝える