技術書

リーダブルコードまとめ

More than 3 years have passed since last update.

評価の高い「リーダブルコード」読んだのでまとめておく。

↓こちら

読みやすコードを書くための習慣やテクニックをまとめてある良書。
とても簡潔にまとまっているので、活字嫌いなエンジニアでもぜひともおすすめしたい一冊。

以前、ビジネス文書研修なるものを受けた事があるが、内容にかなり共通点がある。
日本語だろうが、プログラミングだろうが、読み手にやさしい書き方というものがあるのだ。

第一部 表面上の改善

1章 理解しやすいコード

優れたコードとは何か。それは読みやすさである!これがこの本のテーマです。
ステップ数が少ない事よりも、高度な文法を使うよりも、ずっとずっと重要なことです。なぜならSW開発ではコードを読む事が非常に多いから。

2章 名前に情報を詰め込む

  • 明確な単語を選ぶ。(英語の知識が必要だけど。)

    例えばGetではなく、状況に応じて、DownloadやFetchなど

  • 汎用的な名前を避ける

    tempやretvalなどより、目的や値を表すものであるべき。ただし、スコープにもよる。

  • 接尾辞や接頭辞を使って情報を追加する

    ミリ秒を表す変数に、_msを追加する、など。

  • 名前のフォーマットで情報を伝える

    クラスのメンバ変数にアンダースコアをつけるなど

3章 誤解されない名前

英単語(日本語もね)には曖昧なものが多いので、ネーミングは慎重に。

  • 限界値、包含的または排他的範囲などを意識した名前にする。
  • 妙なプライドは捨て、ユーザーの期待に合わせる事を心がける
  • 複数の名前を検討する。 > template/ reuse / copy / inherit、どれが良いだろうか

4章 美しさ

3つの原則

  • 一貫性のあるレイアウト
  • 似ているコードは、シルエットも似ているように見せる
  • 空行を使って、関連するコードをブロックでまとめる > 視覚的な踏み石を提供できる。ページのなかで自分の場所を見失いにくくなる

シルエットや空白行については、ビジネス文書研修でも意識するように言われた事。

5章 コメントすべきことを知る

読み手の立場になって何が必要になるかを考え、そうでないものは書かない。
嵌りそうな罠を告知する。

6章 コメントは正確で簡潔に

  • 「これ」や「それ」のような代名詞は避ける
  • コメントに含める入出力の実例を慎重に選ぶ。

第2部 ループとロジックの単純化

7章 制御フローを読みやすくする

ここからは、少し深く、ループやロジックレベルの話。

  • 条件式は、左側が調査対象、右側が比較対象
ヨーダ記法
if (NULL == obj)

左側に値を持ってくるのは、obj = NULLなどと書いてしまうのを予防するためのものだが、こういったミスについて最近のコンパイラは警告をしてくれる。それよりは読みやすさを選ぶべき。

  • 三項演算子を使うのは良いが、1行で書くことにこだわってはいけない。読みやすさを重視しべし。
  • returnを複数箇所で呼んではいけないなんて、全くのナンセンス。むしろ読みにくさを生む。
  • goto文も、使い方を間違わなければ問題ない。例えば、関数の下部においたexitと一緒に使う時
gotoの良い使い方
if (obj == NULL) goto exit;
...
exit:
  fclose(filed);
  return;
  • 括弧のネストは浅くする。読み手が精神的スタックを使わないといけないので。

8章 巨大な式を分割する

この本を読む中で、最も「目からウロコ」だったものが、次の2つ、
* 説明変数
読みにくいコードには敢えて変数を作り、説明する

説明変数-before
if line.split(':'[0].strip() == "root";

これを、以下のように記述する。

説明変数-after
username = line.split(':'[0].strip();
if username == "root"

この配慮が素敵。

  • 要約変数
要約変数-before
if (request.user.id == document.owner_id) {
  // Onwerの場合
}
...
if (request.user.id != document.owner_id) {
  // Ownerでない場合
}

これを

要約変数-after
final boolean user_owns_document = (request.user.id == document.owner_id);
if (user_owns_document) {
  // Onwerの場合
}
...
if (!user_owns_document) {
  // Ownerでない場合
}

もう一度言おう。この配慮が素敵だ。こんなコードならreviewしたい。

  • 「頭が良い」コードで1行にまとめて書くよりも、複数行に分割して書いたほうが何がしたいのかわかりやすい
  • ロジックを正しく理解して、簡潔で優雅なコードを発見する
  • 変数や関数をうまく利用して巨大な式を分割する

9章 変数と読みやすさ

  • 役に立たない一時変数は削除する
  • 変数のスコープを小さいものにする。

例えばグローバル変数は、どこでどのように使われるか追跡する必要があり、把握するのに時間がかかる

  • 宣言・定義の位置は、使う直前に

第3部 コードの再構成

ここ以降はもう少しに大きな話

10章 無関係の下位問題を抽出する

関数の目的を明確にし、直接的に関係なものは別の関数にしてまとめる。

  • 純粋なユーティリティコードとして抽出すれば、別のプロジェクトからも再利用できる
  • 改善も楽にできる

11章 一度に一つのことを

一度に複数の事をやるコードは理解しにくい。
やることを整理して、分割するべき。

12章 コードに思いを込める

自分よりも知識の少ない人が理解できるような、簡単な言葉で説明する能力が大切。
コードも簡単な言葉で書くべき。

  • 解決策をコメントで説明する

13章 短いコードを書く

  • 最も読みやすいコードは何もかかれてないコードだ
  • 最も簡単に問題を解決できるような要求を考える
  • 定期的にすべてのAPI・モジュール・を読んで、ライブラリに慣れ親しんでおく。新しいコードを書いている時に、「ちょっとまてよ、これはAPIで見たような・・・」と思い出すことができる。

第4部 選抜テーマ

14章 テストと読みやすさ

テストは似たコードが続くような場合が多いので、読みやすさと保守性を高めやすい。
* テストを読みやすく、保守しやすく作る。

大切でない詳細はユーザーから隠し、大切な詳細は目立つようにする

  • エラーメッセージを読みやすく自作する
  • テスト関数は、テスト対象、テスト番号などがわかるようにする。

15章 「分・時間カウンタ」を設計・実装する

実践編。割愛。

付録 あわせてよみたい

コードコンプリート

リファクタリング

Effective Java

プログラム書法

達人プログラマー