Readable Code を読む
今までほぼ我流でコーディングしてきたので,ずっとどうにかしたいと思っていました.
そんなときに,O'REILLYの Readable Code を奨めてもらったので,読んで自分用にまとめてみようと思います.
今回の内容は,第1部と第2部です.
はじめに・第1章はこちら
第1部と第2部はこちら
第3部と第4部はこちら
本書は次のリンク先等で入手できます.
Readable Code
第1部 表面上の改善
処理内容を変えない状態で,いかに読みやすいコードにするかというお話.
主に,名前の付け方やレイアウトのコツのお話.
2章 名前のつけ方
変数,関数,クラス等は見てすぐに意味が分かる名前が良い.
名前に情報を詰め込む.名前は短いコメントである.
- 具体的な名前をつける(tmpやsizeなど,汎用的・抽象的な名前はなるべく避ける)
- 単語を加えて情報を追加する(getPage()のPageなど)
- 名前の長さ
スコープ(その名前が**「見える」**コードの行数)の長さに合わせて長さを考える.
使用範囲が小さければ,短い名前でも良い.
- 単語の省略形
基本的に避けた方が良いが,一般的なものであれば使用して良い.
(evaluation を eval,document を doc など)
- 名前のフォーマットで情報を伝える
- クラス : CamelCase
- 変数名 : lower_separeted
- 定数 : CONSTANT_NAME
variable_
のように最後にアンダースコアをつけて,区別するなども良い.
3章 誤解されない名前
自分がつけた名前が,別の意味に解釈されることはないか自問自答する.
以下,状況別のおすすめ単語まとめ.
-
max
,min
: 限界値を含めるとき -
first
,last
: 範囲を指定するとき(最後を含める) -
begin
,end
: 範囲を指定するとき(最後を含めない) -
is
,has
: 関数等がブール値を返すとき- 何が
True
で何がFalse
かを明確にすること - 肯定系を使うこと
- 何が
4章 見た目の美しさ
コードを読みやすくするための余白,配置,順序についての説明
- 一貫性のあるレイアウト
- 書き方を統一する
- 関連するコードはまとめてブロックにする
- 同じ処理の関数化
- コメント区切りで処理をグループ化
5章 コメントのつけ方
コメントの目的は,書き手の意図を読み手に知らせること.
優れたコード > ひどいコード + 優れたコメント
コードを理解するのに役立つものなら何でもいいから書こう
コメントすべきでないこと
- コードからすぐに分かることをコメントに書かない
- コメントが不要なくらい,良い名前を関数や変数につける
コメントすべきこと
-
自分の考えを記録する(コードの意図を書く)
- 〜すればよかったとか,〜より高速だったとか
- コードの欠陥に関するコメントをつける
-
TODO:
あとで手をつける -
FIXME:
既知の不具合があるコード -
HACK:
あまり綺麗じゃない解決策 -
XXX:
危険!大きな問題がある
-
- 質問されそうなことを前もって書く
- ハマりそうな罠を告知する
- **「全体像」**のコメント(クラスや関数の関係性など)
- 処理の要約を書く
6章 コメントは正確で簡潔に
- 曖昧な代名詞は避ける
- 入出力の実例を示す
第2部 ループとロジックの単純化
以下のような精神的な荷物を減らすコツのお話.
- 複雑なループ
- 巨大な式
- 膨大な変数
7章 制御フローを読みやすくする
流れるように読めるコードを書く.
コードの読み手が立ち止まったり,読み返したりしないように書く.
- 条件式の引数の並び順
if (length > 10)
- 左 : 調査対象
- 右 : 比較対象
- if文の条件の書き方
- 基本的に肯定形を使う
- 単純な条件を先に書く
- 関心を引く条件や目立つ条件を先に書く
- whileで書き直せるなら,do-while文は避ける
- goto文は基本的に使用しない
- ネストを浅くする
8章 巨大な式を分割する
巨大な式を分割して読みやすくする.
-
説明変数を利用する
username = line.split(':')[0].strip() if username == "root":
-
ド・モルガンの法則を使う
1) not (a or b or c) ⇔ (not a) and (not b) and (not c) 2) not (a and b and c) ⇔ (not a) or (not b) or (not c)
-
複雑なロジックになった場合,他に置き換えられないか考える
9章 変数と読みやすさ
- 不要な変数を削除する
-
制御フロー変数を削除する
- while文を抜ける判定をするだけの変数など
- 変数のスコープ(使用範囲)を縮める
-
グローバル変数を避ける
- どこで使用されているか分かりにくい.追えない.
-
ネスト内での変数定義は言語によってスコープが異なる
- なるべくブロックの外側で定義しておく(ifやwhileの直前など)
- 変数定義の位置を下げる(先頭に定義しなくてもよい)
-
グローバル変数を避ける
- 変数は一度だけ書き込む
- 更新され続ける変数を追跡するのはしんどい
- constやfinalなどのイミュータブルにする方法を使うのも良し