Upgrade to Pro — share decks privately, control downloads, hide ads and more …

リーダブルコードLT

Avatar for tsumiki tsumiki
November 08, 2025

 リーダブルコードLT

エンジニア1年目の時にリーダブルコード輪読会で作成したスライド

Avatar for tsumiki

tsumiki

November 08, 2025
Tweet

More Decks by tsumiki

Other Decks in Programming

Transcript

  1. リーダブルコードとは ・O’REILLY 発行、2012 年に発売された本 ・エンジニアにとってバイブル的な良書 ・より良いコードを書くためのノウハウが書かれている ・プログラミングを始めたばかりの人が読んでも価値があるし、  ある程度経験を積んだ人が読んでも価値がある(と言われている) 全体像 ・一部:表面上の改善(関数・変数・クラス名→命名の改善)

    ・二部:ループロジックの単純化(制御フロー・式の分割・変数のスコープ→クラス単位での改善) ・三部:コードの再構成(オブジェクト指向、全体のロジック、API →全体の改善) ※ 後半にいくに連れてより上流の話になっていく ・四部:テストなど1-3 部では扱いきれなかったもの(このスライドでは省略)
  2. ①情報に名前を詰め込む 1-1. 明確な単語を選ぶ 明確で正確な言い回し NG 例) get → fetch 、download

    size → height 、memoryBytes stop → kill 、pause 2-1. 汎用的な名前を避ける 何にでも使える名前は避ける NG 例) retval → 目的や値を表すものへ tmp → 一時的な情報の保存の の場合は使って良い 2-2. ループイテレータ 複数あるときは説明的な名前に ループイテレータ:i 、j 、k など 説明的な名前: i → user_i 、member_i 、など ②汎用的な名前を使わない 参考:プログラミングでよく使う英単語のまとめ【随時更新】
  3. ③具体的な名前を使う 3-1. 具体的な名前を使う 名前と目的を一致させる 日本語でいう「〇〇が」「〇〇 を」の部分を名前で表す 例) disallow_evil_constructor →disallow_copy_and_assign 4-1.

    値の単位の追加 変数名に単位を入れる 例) start → start_ms size → size_mb limit → limit_kbps delay → delay_secs angle → degrees_cw 4-2. 重要な属性の追加 意味を間違えたとき深刻な被害 が出るところに危険や注意を喚 起する情報の追加 例) データが安全でない → unsafe 〇 〇、untrusted 〇〇 暗号化すべき → plaintext_ 〇〇 ④名前に情報を追加する
  4. ⑤名前の長さを決める 5-1. 名前の長さを決める いい名前 = 「長い名前を避ける」 という暗黙の制約 →どこで折り合いをつけるべきか のガイドライン 5-2.

    短い名前でもいい スコープが小さければ短い名前 でもいい →名前が適用されているコード の行数が小さければ、コード理 解に必要な情報がすぐそばにあ るため 5-3. 単語補完機能を使う エディタの単語補完機能を使う ことで正確な単語が入力できる 例) InteliJ IDEA → Alt-/
  5. ⑤名前の長さを決める 5-4. 省略形 スラングな省略形以外は使わない 例) evaluation → evail document →

    doc NG 例) BackEnd → BE 5-5. 不要単語の切り捨て 削除しても問題ない単語は切り 捨てる 例) DoServeLoop → ServeLoop ConvertToString → ToString 6-1. フォーマットで伝える フォーマットの違いで情報を伝 える 例) クラス名 → キャメルケース 変数名 → スネークケース HTML id → スネークケース class → ケバブケース ⑥フォーマットで情報を伝える
  6. ①例)filter() 、Clip() 1-1. 例1)filter() あいまいな言葉 - 選択か除外か分からない 例) 選択 →

    select() 除外 → exclude() 1-2. 例2)clip() あいまいな言葉 - 動作が特定できない 例) 最後の文字から削除 → remove 最大文字まで切り詰め → truncate
  7. ②限界値/ 範囲/ 排他的範囲/ ブール値 2-1. 限界値 限界値を含めるとき(~ 以上、~ 以下) →min

    とmax を使う 例) max_ 〇〇 min_ 〇〇 2-2. 範囲 範囲を示すもの →first とlast を使う (min 、max でも良い) 例) set.PrintKeys(first="a", last="e") print int_rang(min=2, max=4) 2-3. 包含/ 排他的範囲 最初は含むが最後の要素は含ま ないもの →begin とend を使う 例) 何時から何時まで開催など
  8. ②限界値/ 範囲/ 排他的範囲/ ブール値 2-4. ブール値 ブール値を返す関数 →true とfalse の意味が通るよう

    な名前にする 例) is 、has 、can 、should などを つけて分かりやすく 3-1. ユーザーの期待 エンジニア業界のスラングを理解して 名前に反映させる 例) get() 、〇〇.list() 、〇〇size() → 軽量なメソッド generate 〇〇() 、〇〇.countSize() → 重量なメソッド ③ユーザーの期待に合わせる ④複数の名前の検討 4-1. 複数の名前の検討 類義語を調べて比較する → 適切な名前を選ぶ
  9. ③ブロック分け 3-1. 宣言をブロックにまとめる 単位を作ってブロックにまとめる 例) // ユーザーの友達取得 friends = user.friends()

    // メールアドレスのインポート contacts = import_contacts(user.emai) 3-2. 段落に分割する コードを段落分けする →空行を使って、ブロックを論 理的な段落に分ける
  10. ①自分の考えや気付き 1-1. 採用理由 1-2. 開発中の気付き 開発中に気付いた欠陥などを, 「Todo :」,「Fix :」を使っ てメモしておく(チームで事前

    に統一しておく) 他にも実装方法やライブラリが ある中,なぜ他の方法ではな く,この手法を採用しているの か 1-3. 定数の設定理由 定数や値の設定理由 ex) なぜこのリストは1000 まで 入るようにしているのか,など
  11. ②読み手の理解を促進するためのメモ 2-1. 詰まりそうな箇所 2-2. プログラムの概要 ファイルやクラスには全体像を コメント ex) これは〇〇をするためのクラ スです,使い方は△です

    読み手が「えっ?」っとなりそ うなところをあらかじめ予想し て,コメントで書いておく 2-3. ロジックの説明 ロジックは改行を入れるなどし てブロックに分け,各ブロック にはコメントを付けて概要を補 足 // ユーザーID 取得 //ID を用いてDB からデータ取得
  12. コメントの情報密度を 高めるために 1-1. 代名詞は使わない データをキャッシュに入れる.ただ し,先に” その” サイズをチェックす る →データ?キャッシュ?

    1-2. 動作を正確に記述 // このファイルに含まれる行数 を返す ↓ // このファイルに含まれる改行 文字('/n' )を数える 1-3. 専門用語を用いる 抽象度を下げるために,コンピ ュータの専門用語を用いる ・ヒューリスティック ・ブルートフォース ・ナイーブソリューション
  13. ①条件式の引数の並び順 1-1. 条件式の引数 左:調査対象(~ はの部分) 右:比較対象 例) if(length >=10) →

    ◯ if(10 <= length) → × 2-1. if/else のルール ①肯定形 > 非定形 - ! はなるべく使わない ②単純な条件を先へ -if とelse が同じ画面に表示される ③目立つ条件を先へ ②if/else のルール
  14. ③三項演算子、do/while ループ、goto 3-1. 三項演算子 三項演算子は基本使わない (条件 ? a : b

    ) →1 行で書いた方が読みやすい 場合のみ使う 3-2. do/while ループ do/while ループは基本使わない →while ループで書く 3-3. goto goto は基本使わない →普通のループに置き換える
  15. ④ネストを浅くする 4-1. ネストを浅くする ネストの深いコードは読みにくい →1 つのネスト内に書くコードは なるべく簡潔になるようにする。 4-2. ループ内部のネストの削除 ループ内部でネストしているコー

    ドは読みにくい →書き方変える/ ループを分ける。 ⑤早めに返す 5-1. 早めに返す 関数で早めに返してあげると、 ネストを削除したりコードをク リーンにしたりできる。
  16. ⑥実行の流れを追いやすく 6-1. 実行の流れを追えるか 実行の流れを追いやすいコード を書く →追うのが難しくなる構成要素 をなるべく少なくする。 例) スレッド、シグナル/ 組み込み

    ハンドラ、無名関数、仮想メソ ッド 6-2. 新鮮な目で見る 変更を加えるときはコードを新 鮮な目で見る →書いている人にとっては簡潔 な変更でも初めて見た人には分 かりづらいときがある。
  17. ①説明変数 1-1. 説明変数 式の意味を説明する変数 例) if line.split[0].strip() == "root": ↓

    username = line.split[0].strip() if username == "root": 1-2. 要約変数 式を代入しておく変数 →大きなコードの塊は変数に代 入すると読みやすくなる 例) if(request.user.id == document.owner_id) ↓ user_owns_document = ... ②要約変数
  18. ③ド・モルガン法則 3-1. ド・モルガン法則 not(a or b or c) ⇅ (not

    a) and (not b) and (not c) not(a and b and c) ⇅ (not a) or (not b) or (not c) not を分配してand/or を反転させる 4-1. 短略評価 短略評価: 論理演算子(&&, || )は左辺を評 価した時点で式全体の真偽値が 決定し右辺を評価する必要がな いもの →長すぎる式の場合は、変数を 使って分割する ④短絡評価
  19. ①変数を削除する 1-1. 役に立たない一時変数 now = datetime.datetime.now() root_message.last_view_time = now ←now

    っていう一時変数いらない  直接代入しちゃえばいい 1-2. 制御フロー変数の削除 boolean done= false; while( 条件 && !done){   → ... if(...) { done=true; continue; } } 制御フロー変数done の削除 while( 条件 ){ ... if(...) { break; } }
  20. ②変数のスコープを小さく する(変数はできる限り近 くで宣言する) 2-1. グローバル変数 色々なところから値が変更され てプログラムが複雑になり、処 理の流れを追いづらくなる 問題があったときに原因が何な のか特定しづらくなる

    想定外のところで値が変更され てしまう 極力使用を避ける 2-2. インスタンス変数 関数の引数で足りるデータ をインスタンス変数にしな い 加工した値をインスタンス 変数に保持しない プログラムで取得できる情 報をインスタンス変数に保 持しない 必要になったときに,使う直前で初 めて定義して、スコープを最小にす るよう心がける。 説明変数は積極的に使って良い 2-3. ローカル変数 参考:qiita 「良いコードの書き方」
  21. ①プロジェクト固有のコードから汎用コードを分離する 理由: 1. 呼び出し側のコードが簡潔になる 2. 再利用できる 3. 改善が楽になる ②純粋なユーティリティコード -

    プログラムの核となる基本的なタスクは汎用コードと して分離する 例)ファイルの読み込み、ハッシュテーブルの使用 ポイント
  22. 「権限あり/ なし」,「時間/ 銘柄/ 価 格」など,ロジックを構成する上で重要 となりそうなキーワードに着目する 2-2. 簡潔にコードを書く ロジックの説明を実装する再,難 しい/

    不自然なコードではなく, 他者が読みやすいよう,できるだ け簡潔で自然なコードを書く ②説明に合わせてコードを書く 2-1. キーワードやフレーズ に注目する 2-3. ライブラリを知る 簡潔なコードを書くために,ライ ブラリが何を提供してくれてるか を知ることが欠かせない.ライブ ラリの内容を知る時間を作り,実 際に利用する
  23. ①不必要な機能をプロダクトから 削除する 1-1. 必要機能の見積もり プロジェクトを開始するときに は,カッコいい機能のことを考 え,そしてプロダクトに書かせ ない機能を過剰に見積もりがち 1-2. 実装労力の過小評価

    プログラマは, ・実装コスト ・保守/ 文章化コスト を過小評価しがち 1-3. ミニマル 不必要な機能をプロダクトから削 除する.過剰な機能は持たせな い.ミニマルなプロダクトを維持 s する
  24. 2-1. 要求の正しい評価 すべてのプログラムが,高速 で,100% 正しくて,あらゆる ケースをうまく処理できる必要 はない.どの程度の要求を満た せばいいのか,実装前に適切に 評価する 2-2.

    最も簡単なプログラム 要求を正しく見積もった上で,そ の要求を満たす最もシンプルで簡 単なプログラムを実装する.難し いロジックを組む必要はない ②最も簡単に要求を満たす実装 方法を考える
  25. 3-1. ユーティリティ化 重複コードを汎用的な「ユーテ ィリティコード」にする ≒オブジェクト指向 3-2. コードの削除 「コードをせっかく書いたから, 削除したくない」そんなのどうで もいいんだよ!

    未使用のコードは無用の機能はど んどん削除しよう ③コードを小さく保つ 3-3. 外部リソースの利用 - 言語の標準ライブラリ - 外部API - Unix コード を用い,コード量を減らす " たまには標準ライブラリのすべ ての関数を15 分かけて読んでみ ろ!"