LoginSignup
15
15

More than 3 years have passed since last update.

リーダブルコード定石

Last updated at Posted at 2020-08-18

ということで、リーダブルコードの定石として使えそうなものを章ごとに抽出。
対象者はリーダブルコードの読者です。
弊記事を通して、何度も定石を思い出しリーダブルコードを読みなおし、自分の肉としてください。

(ただし、これらに囚われすぎず、プロダクトが動くのが第一!!というのが本音なのは内緒)

なお、チェックリストは既出でした
「リーダブルコード適用 チェックリスト」を作ってみました

が、弊記事は、より本書の内容に踏み込んでいます。
では行きましょう。(自己満自己理解のための、あうとぷ記事です...

1章 理解しやすいコード

  • コードは理解しやすく
  • コードは他人が最短時間で理解できるように書く

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

  • 明確な単語を選ぶ
    • Getではなく、状況に応じてFetchやDownload
  • tmpやretvalなどの汎用的な名前を避ける
    • retvalという名前には情報がない。変数の値を表すような名前を使う
    • tmpという名前は、生存期間が短くて、一時的な補完が最も大切な変数にだけ使う
    • tmp・it・retvalのような汎用的な名前を使うときは、それ相応の理由を用意
  • 具体的な名前を使って、物事を詳細に説明する
    • ServerCanStart() より CanListenOnPort() のほうが明確
  • 変数名に大切な情報を追加する
    • ミリ秒を表す変数名には、後ろに_msをつける。これからエスケープが必要な変数名には、前にraw_をつける
  • スコープの大きな変数には長い名前を付ける
    • スコープが数画面に及ぶ変数に1~2文字の短い暗号めいた名前を付けない。短い名前はスコープが数行の変数につける
  • 大文字やアンダースコアなどに意味を含める
    • クラスのメンバ変数にアンダースコアを付けて、ローカル変数と区別する

3章 誤解されない名前

  • 名前が「ほかの意味と間違えられることはないだろうか」と何度も自問自答する
  • 上下の限界値を決めるときは名前の前にmax_やmin_
  • 包含的範囲ではfirstやlast
  • 包含/排他的範囲ではbeginとend
  • ブール値への名前付けではisやhasを使い、否定形を避ける
  • ユーザーの期待に注意する
    • get()やsize()には軽量なメソッドが期待される
  • 複数の名前を検討する

4章 美しさ

  • 読み手が慣れているパターンと一貫性のあるレイアウトを使う
    • コードの列を整理して概要を把握しやすく
    • 一貫性のあるスタイルは「正しい」スタイルよりも大切
  • 似ているコードは似ているように見せる
    • 意味のある順番を選んで、常にその順番を守る
  • 関連するコードをまとめてブロックにする
    • 複数コードブロックで同じようなこと→シルエットも同じにそろえる
    • 空行を使って大きなブロックを論理的な「段落」に分ける

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

  • コメントすべきで「ない」こと
    • コードからすぐに抽出できること
    • ひどいコードを補う →コメントを書くのではなくコードを修正
  • 記録すべき自分の考え
    • なぜ他のやり方でなく、そうするのか
    • コードの欠陥をTODO:やXXX:などの記法で示す
    • 定数の値にまつわる「背景」
  • 読み手の立場で考えて生み出すコメント
    • 質問されそうなこと
    • ハマりそうな罠の告知
    • ファイルやクラスの全体像
    • コードブロックの概要

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

  • コメントは領域に対する情報の比率を高くする
  • 曖昧代名詞を避ける
    • 複数可能性があるものに、指示代名詞を避ける
  • ブラッシュアップ歯切れ悪い文章
  • 関数動作を正確に
  • 入出力のコーナーケースに実例の選定
  • コードの意図は、詳細レベルではなく高レベル
  • 「名前付き引数」コメの使用
  • 情報密度の高い言葉

7章 ループとロジックの単純化

  • 条件やループなどの制御フローはできるだけ「自然」にする。コードの読み手が立ち止まったり読み返したりしないように書く
  • 条件は肯定形
    • if(!debug)よりif(debug)
  • 単純な条件を先に書く
  • 関心を引く条件や目立つ条件を先に書く
  • 行数を短くするよりも、他人が理解するのにかかる時間を短くさせる
  • 基本的にはif/elseを使う。三項演算子はそれによって簡潔になるときにだけ使う
  • do/whileループを避ける
  • 関数から早く返す
  • 基本的にgotoは使わない
  • ネストを浅く
  • 変更するときはコードを新鮮な目で見る。一歩座がって全体を見る
  • ループ内部のネストを削除

8章 巨大な式を分割する

  • 巨大な式は飲み込みやすい大きさに分割
    • 説明変数の導入
    • 要約変数の導入
  • ド・モルガンを使う
  • 「頭がいい」コードに注意。後で他人が読む際分かりにくくなる

9章 変数を削除する

  • 邪魔な変数を削除
    • 中間結果の変数を削除
  • 変数のスコープをできるだけ小さく
  • 変数を操作する場所を増やさない
  • 一度だけ書き込む変数を使う

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

  • 関数やコードブロックを見て「このコードの高レベルの目標」を自問
  • コードの各行に対して「高レベルの目標に直接的に効果があるか、無関係の下位問題を解決しているのか」を自問
  • 無関係の下位問題を解決しているコードが相当量あれば、抽出して別関数にする

11章 一度に一つのことを

  • コードは1つずつタスクを行うようにする
    • コードが行っている「タスク」をすべて列挙
    • タスクをできるだけ異なる関数に分割

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

  • ロジックを明確に説明する
  • ライブラリを知る
  • 解決策を言葉で説明する
  • 手法を再帰的に適用する
  • 問題を声に出して説明してみる

13章 短いコードを書く

  • 最も読みやすいコードは何も書かれていないコード
  • 不必要な機能をプロダクトから削除する。過剰な機能は持たせない
  • 最も簡単に問題を解決できるような要求を考える
  • 定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しむ

14章 テストと読みやすさ

  • テストのトップレベルはできるだけ簡潔に。入出力のテストはコード1行で記述が理想
  • テストが失敗したらバグの発見や修正がしやすいエラーメッセージを表示
  • 安心してテストの追加や変更ができるように、テストコードを読みやすく
  • テスト関数に説明的な名前をつけ、何をしているか明確に
  • コードを完全にテストする最も単純な入力値の組み合わせを選択
  • テストには最もキレイで単純な値を選ぶ

一つでも改善すると、未来のコード読者、自分が喜ぶはず!

15
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15