近況報告
エンジニア転職成功しました。YouTubeでエンジニア転職したい方向けに情報発信しています。
今回は、都内エンジニアメンバーで隔週で集まって開催している「コミット会」で発表した
リーダブルコードの第一部について、まとめていきます。
リーダブルコードってどんな本?
本書が伝えたいこと
- 「コードは理解しやすくなければいけない」 ということ
- 読みやすさの基本定理があり、それは「他の人が読んだ時に、最短時間で理解できるコード」
- 例えると、処理は同じだが理解にかかる平均的な時間が10分と1分のコードがあるとする。
- この本では、10分で理解できるコードを1分で理解できるように書く方法を、「様々なシーン」ごとに、わかりやすく解説している
- 汚いコード(10分)→綺麗なコード(1分) する方法を、実例を用いて紹介している
1部〜4部まとめ
- 第一部(今回まとめたのはこれ)
- 表面上の改善
- 2章〜6章
- 第二部
- ループとロジックの単純化
- 第三部
- コードの再構成
- 第四部
- 選抜テーマ
1部 表面上の改善
↓には、「表面上の改善」の3つを示している。これらは、すぐに修正可能。
かつ、全てのコードに影響するのでこのテーマはすごく大事
- 優れたコメントを書く
- コードを綺麗にフォーマットする → リウァくたリング
2章 名前に情報を詰め込む
鍵となる考え
- 名前に情報を詰め込む
明確な単語を選ぶ
もっと「カラフル」な単語を探す
鍵となる考え
- 気取った言い回しよりも明確で正確なほうがいい
tmpやretvalなどの汎用的な名前を避ける
アドバイス
- retvalという名前には情報がない。変数の値を表すような名前を使おう
- tmp アドバイス
- tmpという名前は、生存期間が短くて、一時的な保管が最も大切な変数にだけ使おう ループイテレータ
- ネストしたforループでは、ループイテレータも考えて命名するとバグを発見しやすくなる
#### 時/分/秒は、i/j/k と表すより、time/minute/secondと表す方が理解しやすく、バグも発見しやすい
for(int i = 0; i < 24; i++)
for(int j = 0; j < 60; i++)
for(int k = 0; k < 60; k++)
# 本来は7:30:00の時に「朝です」と出力したいが、↓だと7:00:30に「朝です」と出力される(バグ)
if(i == 7 && k == 30 && j == 00){
print '朝です';
}
汎用的な名前のまとめ
- tmp/it/retval のような汎用的な名前を使うときは、それ相応の理由を用意しよう
抽象的な名前よりも具体的な名前を使う
- 例:DISALLOW_EVIL_CONSTRUCTORS
- 例:--run_locally
名前に情報を追加する
値の単位
- その他の重要な属性を追加する
名前に長さを決める
- スコープが小さければ短い名前でもいい
- 長い名前を入力するのは問題じゃない
- 頭文字と省略形
- 不要な単語を投げ捨てる
名前のフォーマットで情報を伝える
- その他のフォーマット規約
まとめ
テーマ
- 名前に情報を詰め込む
- 明確な単語を選ぶ
- tmpやretvalなどの汎用的な名前を避ける
- 具体的な名前を使って、物事を詳細に説明する
- 変数名に大切な情報を追加する
- スコープの大きな変数には長い名前をつける
- 大文字やアンダースコアなどに意味を含める
3章 誤解されない名前
鍵となる考え
- 名前が「他の意味と間違えられることはないだろうか?」と何度も自問自答する。
例:filter()
例:Clip(text, length)
限界値を含めるときはminとmaxを使う
アドバイス
- 限界値を明確にするには、名前の前にmax_やmin_をつけよう
範囲を指定するときはfirstとlastを使う
包含/排他的範囲にはbeginとendを使う
- 例:4/12のイベントの開催日時を範囲指定する
- 4/12:0:00(begin)→4/12:23:59:59(end)
- 包含/排他的範囲ではない例
- 4/12:0:00(begin)→4/13:00:00:00(end)
ブール値の名前
ユーザの期待に合わせる
- 例:get*()
- 例:list::size()
複数の名前を検討する
まとめ
- 最善の名前とは、「誤解されない名前」である
4章 美しさ
読みやすくするための施策は以下3つに気をつけること
- 余白
- 配置
- 順序
具体的には
- 読み手が慣れているパターンと一貫性のあるレイアウトを使う
- 似ているコードは似ているように見せる
- 関連するコードをまとめてブロックにする
なぜ美しいが大切なのか
なぜ美しいが大切なのか
- 見た目が美しいコードのほうが使いやすいほうが明らか
一貫性のある簡潔な改行位置
メソッドを使った整列
縦の線をまっすぐにする
一貫性と意味のある並び
宣言をブロックにまとめる
コードを「段落」に分割する
個人的な好みと一貫性
鍵となる考え
- 一貫性のあるスタイルは「正しい」スタイルよりも大切
まとめ
- 複数のコードブロックで同じようなことをしていたら、シルエットも同じようなものにする
- コードの「列」を整列すれば、概要が把握しやすくなる
- ある場所でA・B・Cのように並んでいたものを、他の場所でB・C・Aのように並べてはいけない。意味のある順番を選んで、常にその順番を守る
- 空行を使って大きなブロックを論理的な「段落」に分ける
5章 コメントすべきことを知る
鍵となる考え
- コメントの目的は、書き手の意図を読み手に知らせることである。
コメントするべきでは「ない」こと
鍵となる考え
- コードからすぐにわかることをコメントに書かない。
例:
// 削除フラグがある場合、削除メッセージを表示
$deletemsg = '';
if ($_SESSION['deleted'] == 'true') {
$deletemsg = '投稿は削除されました';
};
$_SESSION['deleted'] = 'false';
- コメントのためのコメントをしない
- コメントで使われている専門用語を解説するコメントのこと
- ひどい名前はコメントをつけずに名前を変える
- 例:Titleを取得する関数名
- 関数名(酷い) titlesyutokukansuu($title) # $titleは記事タイトルを取得する
- 関数名(変更後) fetchPageTitle($title)
自分の考えを記録する
- 「監督のコメンタリー」を入れる
- 「なぜ」こうなってるのか
- コードの欠陥にコメントをつける
- 定数にコメントをつける
読み手の立場になって考える
- 質問されそうなことを想像する
- ハマりそうな罠を告知する
- 全体像のコメント
- 要約コメント
ライターズブロックを乗り越える
まとめ
- コメントの目的とは、コードの意図を読み手に理解してもらうこと
コメントすべきではないこと
- コードからすぐに抽出すること
- ひどいコード(例えば、ひどい名前の関数)を補う「補助的なコメント」コメントを書くのではなくコードを修正する
記載すべき自分の考え
- 何故コードが他のやり方ではなくこうなっているのか(監督コメンタリー)
- コードの欠陥をTO####やXXX:などの記法を使って示す
- 定数の値にまつわる「背景」
読み手の立場になって考える
- コードを読んだ人が「えっ?」と思うところを予想してコメントを付ける
- 平均的な読み手が驚くような動作は文書化しておく
- ファイルやクラスには「全体像」のコメントを書く。
- 読み手が細部にとらわれないように、コードブロックにコメントをつけて概要をまとめる
6章 コメントは正確で簡潔に
鍵となる考え
- コメントは領域に対する情報の比率が高くなければいけない
コメントを簡潔にしておく
あいまいな代名詞を避ける
- 名詞を代名詞に代入するといい
- 代名詞(それ) = 名詞(データ)
- →表現が面白い
端切れの悪い文章を磨く
関数の動作を正確に記述する
入出力のコーナーケースに実例を使う
コードの意図を書く
「名前付き引数」コメント
情報密度の高い言葉を使う
まとめ
- 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
- 関数の動作はできるだけ正確に説明する
- コメントに含める入出力の実例を慎重に選ぶ
- コードの意図は、詳細レベルではなく、高レベルで記述する
- よくわからない引数にはインラインコメントを使う(Function(/* arg = *####..))
- 多くの意味が詰め込まれた言葉や表現を使って、コメントを簡潔に保つ
EOF;