リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- オライリージャパン (2012年6月23日発売)
- Amazon.co.jp ・本 (260ページ)
- / ISBN・EAN: 9784873115658
感想・レビュー・書評
-
実は読んでいなかったシリーズ。
文章自体が面白くて楽しめる。詳細をみるコメント0件をすべて表示 -
・命名やコメントは非常に大切
・他の人が読みやすいコードを意識する
・「一度でひとつのこと」を意識してコーディング -
所在: 展示架
請求番号: 007.64 || B66
資料ID: 12300409
プログラムを書いて終わりではなく、読みやすさやわかりやすさを考慮して書くことを学ぶことができる。
選書担当者 : S -
プログラミングでは基本的に、コードは他人(半年後の自分を含む)が読んだ時に理解しやすく書くことが求められます。例えば、実験で使うものであっても、コードが読みやすいことで項目の抜け漏れに気づきやすかったり、後輩が研究を引き継ぐ場合にスムーズだったりと、多くの恩恵があります。これはそんな「読みやすいコード」を書くために、プログラミング初級者から上級者までのすべての人におすすめできる本です。 この本では、「読みやすいコード」を書くためのテクニックが具体例付きで紹介されています。例えば、より良い関数名の付け方、コメントではどんな事を書くべきか、複雑なコードをどう分けていくかなどです。プログラミング関係の本というと読むのが難しいイメージがあるかもしれませんが、この本では技術的な話はほとんど登場しません。代わりにプログラムの例を挙げ、どこがダメでどう直すべきかが理由付きで丁寧に解説されており、スラスラと読んでいくことができます。読み終えましたら是非、普段のプログラミングでこれらのテクニックを実践してみてください!
(ラーニング・アドバイザー/情報 YAGAWA)
▼筑波大学附属図書館の所蔵情報はこちら
https://www.tulips.tsukuba.ac.jp/opac/volume/1915094 -
どうすれば他人が理解しやすいコードになるかを解説した本。
表面上の工夫(変数名など)から設計に関わる部分まで様々なtipsが載っていた。 -
この本を読んで自分のコードを批評してみる。
優れたコードとは見た瞬間に何をしているかが伝わってくるコードのこと。
気になったところ(目次)
2章 明確な単語を選ぶ
カラフルな単語を探す
重要な属性とは
長い名前を入力するのは問題じゃない
不要な単語とは
3章 誤解されない名前
複数の名前を検討する
4章 整列すべきなのか?
(疑)毎回コンマを入れる必要があるってこと?
8章 ドモンガンの法則を使う (疑)どゆこと?
実際にやるとぶつかるところ
-
1章 理解しやすいコード
【鍵となる考え】
・コードは理解しやすくなければいけない
・コードは他の人が最短時間で理解できるように書かなければならない
2章 名前に情報を詰め込む
【まとめ】
・明確な単語を選ぶ。例えば、Getではなく、状況に応じてFetchやDownloadなどを使う。
・tmpやretvalなどの汎用的な名前を避ける。ただし、明確な理由があれば話は別だ。
・具体的な名前を使って、物事を詳細に説明する。ServerCanStart()よりもCanListenOnPort()のほうが明確だ。
・変数名に大切な情報を追加する。ミリ秒を表す変数名には、後ろに_msをつける。これからエスケープが必要な変数名には、前にraw_をつける。
・スコープの大きな変数には長い名前をつける。スコープが数画面に及ぶ変数に1~2文字の短い暗号めいた名前をつけてはいけない。短い名前はスコープが数行の変数につけるべきだ。
・大文字やアンダースコアなどに意味を含める。例えば、クラスのメンバ変数にアンダースコアをつけて、ローカル変数と区別する。
3章 誤解されない名前
【まとめ】
最善の名前とは、誤解されない名前である。つまり、君のコードを読んでいる人が、君の意図を正しく理解できるということだ。英語の単語は、filterlengthlimitのように、プログラミングに使うには意味があいまいなものが多い。
名前を決める前に反対意見を考えるなどして、誤解されない名前かどうかを想像してみよう。最善の名前というのは、誤解されない名前である。
上下の限界値を決めるときには、max_やmin_を前につけるといい。包含的範囲であれば、firstやlastを使うといいだろう。包含/排他的範囲であれば、beginとendがイディオムなのでそれを使う。プール値に名前をつけるときには、それがブール値だとわかるようにisやhasなどの単語を使う。disable_ss1のような否定形は避ける。
単語に対するユーザの期待にも注意する。例えば、get()やsize()には軽量なメソッドが期待されている。
4章 美しさ
【まとめ】
誰もが美しいコードを見るのが好きだ。一貫性と意味のあるやり方でコードを「整形」すれば、すばやく簡単にコードを読むことができる。
ここで紹介した技法をまとめよう。
・複数のコードブロックで同じようなことをしていたら、シルエットも同じようなものにする。
・コードの「列」を整列すれば、概要が把握しやすくなる。
・ある場所でA・B・Cのように並んでいたものを、他の場所でB・C・Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る。
・空行を使って大きなブロックを論理的な「段落」に分ける。
5章 コメントすべきことを知る
【まとめ】
・コメントの目的とは、コードの意図を読み手に理解してもらうことである。本章では、コードについてほんやりと考えていたことをハッキリと理解して、実際に書き出すことをやってみた。
コメントすべきでは「ない」こと:
・コードからすぐに抽出できること。
・ひどいコード(例えば、ひどい名前の関数)を補う「補助的なコメント」。コメントを書くのではなくコードを修正する。
記録すべき自分の考え:
・なぜコードが他のやり方ではなくこうなっているのか(「監督コメンタリー」)。
・コードの欠陥をTODO:やXXX:などの記法を使って示す。
・定数の値にまつわる「背景」。
読み手の立場になって考える
・コードを読んだ人が「えっ?」と思うところを予想してコメントをつける。
・平均的な読み手が驚くような動作は文書化しておく。
・ファイルやクラスには「全体像」のコメントを書く。
・読み手が細部に捕らわれないように、コードブロックにコメントをつけて概要をまとめる。
6章 コメントは正確で簡潔に
本章では、小さな領域にできるだけ多くの情報を詰め込んだコメントを書くことについて説明した。具体的なヒントを以下に挙げる。
・複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける。
・関数の動作はできるだけ正確に説明する。
・コメントに含める入出力の実例を慎重に選ぶ。
・コードの意図は、詳細レベルではなく、高レベルで記述する。
・よくわからない引数にはインラインコメントを使う(例:Function(/*arg=*/...))。
・多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ。
7章 制御フローを読みやすくする
【まとめ】
コードの制御フローを読みやすくするために君ができることはいくつもある。
比較(while(bytes_expected > bytes_received))を書くときには、変化する値を左に、より安定した値を右に配置する(while(bytes_received < bytes_expected))。
if/else文のブロックは適切に並び替える。一般的には、肯定形・単純目立つものを先に処理する。こうした基準は衝突することもあるけど、衝突がなければ基準を守っておこう。
三項演算子(?:)・do/whileループ・gotoなどのプログラミング構成要素を使うと、コードが読みにくくなることが多い。代替となるものが必ずあるので、これらは使わないほうがいいだろう。
ネストしているとコードを追うのに集中力が必要になる。ネストが増えるたびに「スタックにプッシュ」することが増える。深いネストを避けるには「直線的」なコードを選択する。
早めに返してあげると、ネストを削除したりコードをクリーンにしたりできる。特に「ガード節」(関数の上部で単純な条件を先に処理するもの)が便利だ。
8章 巨大な式を分割する
【まとめ】
巨大な式を一度に理解しようと思うと難しい。本章では、巨大な式を分割して、読み手が1つずつ飲み込めるようにする方法を説明した。
最も簡単な方法は「説明変数」を導入することだ。大きな式の値を保持する説明変数には、3つの利点がある。
・巨大な式を分割できる。
・簡潔な名前で式を説明することで、コードを文書化できる。
・コードの主要な「概念」を読み手が認識しやすくなる。
その他には、ド・モルガンの法則を使ってロジックを操作する方法がある。これは論理式をキレイに書き直すことにも使える(例えば、if (! (a && !b)) は、if (!a || b) になる)。
複雑な論理条件は 「if (a < b) ...」 のような小さな文に分割した。 本章で取り上げたすべての改善コードには、if文の中身が2行以上含まれていない。これは理想的な状況だ。同じことが常にできるとは限らない。そんなときは、問題を「否定」したり、反対のことを考えてみたりすることが必要になる。
最後に、本章の分割は式を対象にしたものだったけど、巨大なコードブロックにも同じ技法が使える。複雑なロジックを見かけたら、積極的に分割して欲しい。
9章 変数と読みやすさ
【まとめ】
本章では、プログラムの変数はすぐに増えるので、いずれ追跡できなくなるという話をした。変数を減らして、できるだけ「軽量」にすれば、コードは読みやすくなる。具体的には、
・邪魔な変数を削除する。本章では、結果をすぐに使って、「中間結果」の変数を削除する例を示した。
・変数のスコープをできるだけ小さくする。変数を数行のコードからしか見えない位置に移動する。「去る者は日々に疎し」って言うからね(いい意味で)。
・一度だけ書き込む変数を使う。変数に一度だけ値を設定すれば(あるいは、constやfinalなどのイミュータブルにする方法を使えば)、コードが理解しやすくなる。
10章 無関係の下位問題を抽出する
【まとめ】
本章を簡単にまとめると、プロジェクト固有のコードから汎用コードを分離するということだ。ほとんどのコードは汎用化できる。一般的な問題を解決するライブラリやヘルパー関数を作っていけば、プログラムに固有の小さな核だけが残る。
この技法が役に立つのは、プロジェクトの他の部分から分離された、境界線の明確な小さな問題に集中できるからだ。こうした下位問題に対する解決策は、より緻密で正確なものになる。それに、あとでコードを再利用できるかもしれない。
11章 一度に1つのことを
【まとめ】
本章では、コードを構成する簡単な技法「一度に1つのタスクを行う」を紹介した。
読みにくいコードがあれば、そこで行われているタスクをすべて列挙する。そこには別の関数(やクラス)に分割できるタスクがあるだろう。それ以外は、関数の論理的な「段落」になる。タスクをどのように分割するかよりも、分割するということが大切なのだ。いちばん難しいのは、プログラムが行っていることを正確に説明することである。
12章 コードに思いを込める
【まとめ】
本章では、プログラムのことを簡単な言葉で説明する技法について説明した。説明することでコードがより自然になっていく。この技法は思っているよりも簡単だが非常に強力だ。説明で使っている単語やフレーズをよく見れば、分割する下位問題がどこにあるかがわかる。
この「簡単な言葉で説明する」手法は、コードを書くこと以外にも適用できる。例えば、ある大学の計算機センターにはこんな方針があった。プログラムのデバッグに悩む学生は、部屋の隅に置かれたテディベアに向かって最初に説明しなければいけないのである。驚くべきことに、問題を声に出して説明するだけで、学生は解決策が見つかるのだ。この技法は「ラバーダッキング」とも呼ばれている。
問題や設計をうまく言葉で説明できないのであれば、何かを見落としているか、詳細が明確になっていないということだ。プログラム(あるいは自分の考え)を言葉にすることで明確な形になるのである。
13章 短いコードを書く
【まとめ】
冒険。 興奮。 ジェダイはそんなものは求めておらん。―ヨーダ
本章では、できるだけコードを書かないことについて説明した。新しいコードには、テストや文書や保守が必要になる。また、コードが増えると「重く」なるし、開発も難しくなる。
新しいコードを書かないようにするには、
・不必要な機能をプロダクトから削除する。過剰な機能は持たせない。
・最も簡単に問題を解決できるような要求を考える。
・定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しんでおく。
14章 テストと読みやすさ
【まとめ】
テストコードでも読みやすさが大切だ。テストが読みやすければ、テストが書きすくなり、みんながテストを追加しやすくなる。また、本物のコードをテストしやすく設計すれば、コードの設計が全体的に改善できる。
テストを改善する点をまとめよう。
・テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード1行で記述できるといい
・テストが失敗したらバグの発見や修正がしやすいようなエラーメッセージを表示する。
・テストに有効な最も単純な入力値を使う。
・テスト関数に説明的な名前をつけて、何をテストしているのかを明らかにする。Test1()ではなく、Test_<関数名>_<状況>のような名前にする。
特に、新しいテストの追加や修正を簡単にすることが大切だ。
15章 「分/時間カウンタ」を設計・実装する
【まとめ】
最終的にMinuteHourCounterになるまでの手順をおさらいしよう。コードの進化の様子がうまく表されている。
まずは、素朴な解決策から始めた。ここから設計上の課題が2つあることがわかった。速度とメモリ使用量である。
次に、「ベルトコンベヤー」設計を試した。この設計は速度とメモリ使用量の問題は改善できたけど、高パフォーマンスのアプリケーションには適していなかった。また、柔軟性が乏しく、その他の時間帯を扱うにはかなり手を入れる必要があった。
最終的な設計では、複数の下位問題に分割することで、これらの問題を解決した。ボトムアップで3つのクラスを作り、それぞれのクラスで各下位問題を解決するようにした。
•ConveyorQueue
最大のあるキュー。シフト」可能で合計値を保持する。
•TrailingBucketCounter
時間経過に伴ってConveyor Queueを移動する。また、1つの(最新の)時間のカウントを任意の精度で保持する。
•MinuteHourCounter
2つのTrailingBucketCounterを保持する。1つは1分間のカウントで、1つは1時間のカウントだ。 -
おもしろい
もう少しコードが自在にかけるようになったら刺さりそう -
読みやすいコードを書くためのテクニック集。
一番実践しやすいのは、変数名を短いコメントと考えて命名することだと思う。
実際仕事ではかなり適当に変数名を決めていたし、僕のような人間の蓄積によって既存のものもかなり読みにくくなっていた。
一番印象に残っているのは、本質的なテストは大体1行で書けるというやつ。
読みにくいテストコードの例として紹介されていたものが、まさに仕事でよく遭遇したうえに苦労させられたところなので、無駄な情報を切り出すことで本質的な部分を1行に凝縮できるテクニックに感動した。