【書評】リーダブルコード
本棚でもネット記事でもよく見かけており、いつか読んでみたいと思っていたところ、近くの図書館に
偶然あったので、早速借りて読んでみました。主に重要と思った部分の抜粋と要約です。
2名前に情報を詰め込む
省略形
プログラマは、evaluationの代わりにevalを使う。document の代わりにdocを使う。string の代わりにstrを使う。だから、新しいチームメイトもFormatStr()の意味は理解できる。
不要な単語を投げ捨てる
ConvertToString()
を短くしてToString()
にしても、必要な情報は何も損なわれていない。
4美しさ
優れたソースコードは「目に優しい」ものでなければいけない。
僕たちが使っている3つの原則は。
・読み手が慣れているパターンと一貫性のあるレイアウトを使う。
・似ているコードは似ているように見せる。
・関連するコードをまとめてブロックにする。
4.9まとめ
・複数のコードブロックで同じようなことをしていたら、シルエットも同じようなものにする
・コードの「列」を整列すれば、概要が把握しやすくなる
・ある場所でA・B・Cのように並んでいたものを、他の場所でB・C・Aのように並べては
いけない。意味のある順番を選んで、常にその順番を守る
・空行を使って大きなブロックを論理的な「段落」に分ける
5コメントすべきことを知る
「全体像」のコメント
新しいチームメンバにとって、最も難しいのは「全体像」の理解である。クラスはどのように連携しているのか。データはどのようにシステムを流れているのか。エントリーポイントはどこにあるのか。システムを設計した人は、こうしたことについてコメントを書かないことが多い。あまりにも密接にシステムに関わりすぎているからだ。
※コンピューターに近い=低レベル(Low-level)、人間に近い=高レベル(High-level) という
考え方。高レベルなコマンドは抽象化されている。つまり、簡単な処理に見えるものの、実際には
その裏側で低レベルな処理も実装されているが、それは隠れて見えていない。低レベルなコマンドは
記述が単純で抽象的に見えるけど、処理内容は複雑。高レベルなコマンドは抽象的になってはいる
ものの、実装には低レベルな処理も含まれている。🫡🫡🫡
5.4ライターズブロックを乗り越える
プログラマの多くはコメントを書きたがらない。コメントをうまく書くのは大変だと思っているからだ。こうした「ライターズブロック?」を乗り越えるには、とにかく書き始めるしかない。
コメントを書く作業は、3つの簡単な手順に分解できる。
・頭の中にあるコメントをとにかく書き出す
・コメントを読んで(どちらかと言えば)改善が必要なものを見つける
・改善する
5.5まとめ
コメントの目的とは、コードの意味を読み手に理解してもらうことである。本章では、コードについてぼんやりと考えていたことをはっきりと理解して、実際に書き出すことをやってみた。
コメントすべきでは「ない」こと
・コードからすぐに抽出できること
・ひどいコード(例えばひどい名前の関数)を補う「補助的なコメント」。コメントを書くのではなく
コードを修正する。
記録すべき自分の考え
・なぜコードが他のやり方ではなくこうなっているのか(「監督コメンタリー」)
・コードの欠陥を`TODO:`や`XXX:`などの記法を使って示す
・定数の値にまつわる「背景」
読み手の立場になって考える
・コードを読んだ人が「えっ?」と思うところを予想してコメントをつける
・平均的な読み手が驚くような動作は文書化しておく
・ファイルやクラスには「全体像」のコメントを書く
・読み手が細部にとらわれないように、コードブロックにコメントをつけて概要をまとめる
6コメントは正確で簡潔に
6.8情報密度の高い言葉を使う
プログラミングの経験が何年かあれば、同じ問題や解決策が何度も繰り返し登場することに気づいていると思う。こうしたパターンやイディオムを説明するための言葉や表現がある。このような言葉を使えば、コメントをもっと簡潔にできる。
//所在地から余分な空白を除去する。それから「Avenue」を「Ave.」にするなどの整形を施す。
//こうすれば、表記がわずかに違う所在地でも同じものであると判別できる。
以下のようにできる。
//所在地を正規化する(例:”Avenue” -> “Ave.”)
6.9まとめ
本章では、小さな領域にできるだけ多くの情報を詰め込んだコメントを書くことについて説明した。具体的なヒントを以下に挙げる。
・複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
・関数の動作はできるだけ正確に説明する
・コメントに含める入出力の実例を慎重に選ぶ
・コードの意図は、詳細レベルではなく、高レベルで記述する
・よくわからない引数にはインラインコメントを使う
(例:Function(`/* arg = */` …))
・多くの意味が詰め込まれた言葉や表現を使ってコメントを簡潔に保つ
7制御フローを読みやすくする
7.3三項演算子
C言語などでは、
条件 ? a : b
という条件式が書ける。これは、
if(条件){a} else {b}
を簡潔に書いたものだ。
※三項演算子が読みやすくて簡潔な例
time_str += (hour >= 12) ? “pm” : “am”;
※if/else文を使った方がコードが自然になる例
If (exponent >= 0) {
return mantissa * (1 << exponent);
} else {
return mantissa * (1 << -exponent);
}
アドバイス
基本的には if/else
を使おう。三項演算子はそれによって簡潔になるときにだけ使おう。
7.7ネストを浅くする
8巨大な式を分割する
8.1説明変数
式を簡単に分割するには、式を表す変数を使えばいい。この変数を「説明変数」と呼ぶこともある。式の意味を説明してくれるからだ。
If line.split(‘:’)[0].strip() == “root”:
説明変数を使えば、以下のようになる。
username = line.split(‘:’)[0].strip()
If username == “root”:
8.8まとめ
巨大な式を分割して、読み手が1つずつ飲み込めるようにする最も簡単な方法は「説明変数」を導入することだ。それには3つの利点がある。
・巨大な指揮を分割できる
・簡潔な名前で式を説明することで、コードを文書化できる
・コードの主要な「概念」を読み手が認識しやすくなる
9変数と読みやすさ
9.2変数のスコープを縮める
グローバル変数に限らず、全ての変数の「スコープを縮める」のはいい考えだ。それは、一度に考えなければいけない変数を減らせるからだ。 ※スコープを過ぎたらその変数のことを忘れることができる
JavaScriptのグローバルスコープ
JavaScriptでは、変数の定義にvar
をつけないと(例えば、var x = 1
じゃなくて x = 1
にすると)、その変数はグローバルスコープに入ってしまう。グローバルスコープに入ると、全てのJavaScriptファイルや<script>
ブロックからアクセスできてしまう。
<script>
var f = function () {
for (i=0; i<10; i +=1)...
};
f();
</script>
<script>
alert(i);
</script>
※ローカル変数とグローバル変数の使い分けにより、変数のスコープを関数に制限することで、
双方の混線を避けることができる。🫡🫡🫡
9.5まとめ
・邪魔な変数を削除する
・変数のスコープをできるだけ小さくする
・一度だけ書き込む変数を使う
13短いコードを書く
13.6まとめ
・不必要な機能をプロダクトから削除する。過剰な機能は持たせない。
・最も簡単に問題を解決できるような要求を考える。
・定期的に全てのAPIを読んで、標準ライブラリに慣れ親しんでおく。
14テストと読みやすさ
14.10まとめ
テストコードでも読みやすさが大切だ。テストが読みやすければ、テストが書きやすくなり、みんながテストを追加しやすくなる。また、本物のコードをテストしやすく設計すれば、コードの設計が全体的に改善できる。
・テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード1行で記述できるといい
・テストが失敗したらバグの発見や修正がしやすいようなエラーメッセージを表示する
・テストに有効な最も単純な入力値を使う
・テスト関数に説明的な名前をつけて、何をテストしているのかを明らかにする。`Test()`ではなく、
Test_<関数名>_<状況>のような名前にする
⚫︎著者
Dustin Boswell カリフォルニア工科大学理学士号
Trevor Foucher 独立コントリビュータ・マネージャ・テクニカルリード
⚫︎訳者
角 征典 山口県生まれのプログラマ
Discussion