Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
リーダブルコードLT
Search
tsumiki
November 08, 2025
Programming
0
0
リーダブルコードLT
エンジニア1年目の時にリーダブルコード輪読会で作成したスライド
tsumiki
November 08, 2025
Tweet
Share
More Decks by tsumiki
See All by tsumiki
メディアリニューアルした話
tsumiki
0
1
Svelte触ってみた
tsumiki
0
0
スピーダ事業 Product Teamの1週間を考察してみた。
tsumiki
0
0
New Joinerの時に感じていたことを振り返る
tsumiki
0
0
F# AsyncとTask
tsumiki
0
0
F#でちょっとずつ返す
tsumiki
0
0
評価が大事
tsumiki
0
0
Other Decks in Programming
See All in Programming
Implementation Patterns
denyspoltorak
0
130
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
390
Grafana:建立系統全知視角的捷徑
blueswen
0
240
Java 25, Nuevas características
czelabueno
0
120
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
190
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
0
190
SwiftUIで本格音ゲー実装してみた
hypebeans
0
510
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
310
Deno Tunnel を使ってみた話
kamekyame
0
260
Pythonではじめるオープンデータ分析〜書籍の紹介と書籍で紹介しきれなかった事例の紹介〜
welliving
3
630
マスタデータ問題、マイクロサービスでどう解くか
kts
0
140
GoLab2025 Recap
kuro_kurorrr
0
780
Featured
See All Featured
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Applied NLP in the Age of Generative AI
inesmontani
PRO
3
2k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
32
Discover your Explorer Soul
emna__ayadi
2
1k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
110
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
520
The Cult of Friendly URLs
andyhume
79
6.7k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
170
sira's awesome portfolio website redesign presentation
elsirapls
0
91
Transcript
リーダブルコード The Art of Readable Code
リーダブルコードとは ・O’REILLY 発行、2012 年に発売された本 ・エンジニアにとってバイブル的な良書 ・より良いコードを書くためのノウハウが書かれている ・プログラミングを始めたばかりの人が読んでも価値があるし、 ある程度経験を積んだ人が読んでも価値がある(と言われている) 全体像 ・一部:表面上の改善(関数・変数・クラス名→命名の改善)
・二部:ループロジックの単純化(制御フロー・式の分割・変数のスコープ→クラス単位での改善) ・三部:コードの再構成(オブジェクト指向、全体のロジック、API →全体の改善) ※ 後半にいくに連れてより上流の話になっていく ・四部:テストなど1-3 部では扱いきれなかったもの(このスライドでは省略)
「読みやすいコード」 に特化したテーマの本 読みやすい→理解しやすい→ 内部品質/ 外部品質ともに向上→ ” 良い” コードへ
第Ⅰ部 表面上の改善
第1章 理解しやすいコード
いちばん大切な原則 「理解しやすい」とは 理解にかかる時間 > 短いコード 「理解しやすい」コードを書く 他の人が最短時間で理解できる 理解:変更加える/ バグ発見できるレベル 理解にかかる時間を短く→コードを短く
の優先順位 ポイント
第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-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_ 〇〇 ④名前に情報を追加する
⑤名前の長さを決める 5-1. 名前の長さを決める いい名前 = 「長い名前を避ける」 という暗黙の制約 →どこで折り合いをつけるべきか のガイドライン 5-2.
短い名前でもいい スコープが小さければ短い名前 でもいい →名前が適用されているコード の行数が小さければ、コード理 解に必要な情報がすぐそばにあ るため 5-3. 単語補完機能を使う エディタの単語補完機能を使う ことで正確な単語が入力できる 例) InteliJ IDEA → Alt-/
⑤名前の長さを決める 5-4. 省略形 スラングな省略形以外は使わない 例) evaluation → evail document →
doc NG 例) BackEnd → BE 5-5. 不要単語の切り捨て 削除しても問題ない単語は切り 捨てる 例) DoServeLoop → ServeLoop ConvertToString → ToString 6-1. フォーマットで伝える フォーマットの違いで情報を伝 える 例) クラス名 → キャメルケース 変数名 → スネークケース HTML id → スネークケース class → ケバブケース ⑥フォーマットで情報を伝える
第3 章 誤解されない名前
名前をつける上で重要なこと② 「誤解の生まれない名前」 →積極的に誤解を探して名前をつける
①例)filter() 、Clip() ②限界値、範囲、排他的範囲、ブール値 ポイント ④複数の名前の検討 ③ユーザーの期待に合わせる
①例)filter() 、Clip() 1-1. 例1)filter() あいまいな言葉 - 選択か除外か分からない 例) 選択 →
select() 除外 → exclude() 1-2. 例2)clip() あいまいな言葉 - 動作が特定できない 例) 最後の文字から削除 → remove 最大文字まで切り詰め → truncate
②限界値/ 範囲/ 排他的範囲/ ブール値 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 を使う 例) 何時から何時まで開催など
②限界値/ 範囲/ 排他的範囲/ ブール値 2-4. ブール値 ブール値を返す関数 →true とfalse の意味が通るよう
な名前にする 例) is 、has 、can 、should などを つけて分かりやすく 3-1. ユーザーの期待 エンジニア業界のスラングを理解して 名前に反映させる 例) get() 、〇〇.list() 、〇〇size() → 軽量なメソッド generate 〇〇() 、〇〇.countSize() → 重量なメソッド ③ユーザーの期待に合わせる ④複数の名前の検討 4-1. 複数の名前の検討 類義語を調べて比較する → 適切な名前を選ぶ
第4 章 美しさ
コードの「美しさ」の改善 優れたソースコードは「目に優しい」 →ほとんどの時間はコードを読む時間
3 つの原則 ①読み手が慣れてるパターン 一貫性のあるレイアウト ②似ているコードは 似ているように見せる ③関連するコードを まとめてブロックにする →一貫性のあるスタイルは 「正しい」スタイルより大切
ポイント
①一貫性のあるレイアウト 1-1. 一貫性のある改行位置 改行位置はコード全体を通して 同じ位置にする →全体のシルエット的に見やす いコードにする 1-2. 一貫性のある並び 一連のコードでは同じ並び順に
する 1-3. シルエットの統一 複数のコードブロックで同じよ うなことをしていたら、シルエ ットも同じようなものにする
②列の整理 2-1. メソッドを使った整列 メソッドに処理をまとめること で、コードが見やすくなる場合 がある 2-2. 縦の線をまっすぐに 縦の線を揃えることでタイプミ スを見つけやすい、楽に流し読
みできる
③ブロック分け 3-1. 宣言をブロックにまとめる 単位を作ってブロックにまとめる 例) // ユーザーの友達取得 friends = user.friends()
// メールアドレスのインポート contacts = import_contacts(user.emai) 3-2. 段落に分割する コードを段落分けする →空行を使って、ブロックを論 理的な段落に分ける
第5 章 コメントすべきことを 知る
コメントの目的 →コードの意図を,読み手にわかりやすく,で きるだけ短時間で伝えること
①コードからすぐにわかること ②ひどい命名やコードを補うためのコメント →コメントで補うのではなく,コードを直 せ! コメント すべきで ないこと
①実装中の自分の考えや気付き ②読み手の理解を促進するためのメモ コメント すべきこと
①自分の考えや気付き 1-1. 採用理由 1-2. 開発中の気付き 開発中に気付いた欠陥などを, 「Todo :」,「Fix :」を使っ てメモしておく(チームで事前
に統一しておく) 他にも実装方法やライブラリが ある中,なぜ他の方法ではな く,この手法を採用しているの か 1-3. 定数の設定理由 定数や値の設定理由 ex) なぜこのリストは1000 まで 入るようにしているのか,など
②読み手の理解を促進するためのメモ 2-1. 詰まりそうな箇所 2-2. プログラムの概要 ファイルやクラスには全体像を コメント ex) これは〇〇をするためのクラ スです,使い方は△です
読み手が「えっ?」っとなりそ うなところをあらかじめ予想し て,コメントで書いておく 2-3. ロジックの説明 ロジックは改行を入れるなどし てブロックに分け,各ブロック にはコメントを付けて概要を補 足 // ユーザーID 取得 //ID を用いてDB からデータ取得
第6章 コメントは正確で簡潔に
伝えたい内容が齟齬なく, 的確に伝わるようなコメントを書け
①コメントは領域に対する情報の比率が高く なければならない ②情報密度の高い言葉を使う(専門用語、コ ンピュータ用語) ポイント
コメントの情報密度を 高めるために 1-1. 代名詞は使わない データをキャッシュに入れる.ただ し,先に” その” サイズをチェックす る →データ?キャッシュ?
1-2. 動作を正確に記述 // このファイルに含まれる行数 を返す ↓ // このファイルに含まれる改行 文字('/n' )を数える 1-3. 専門用語を用いる 抽象度を下げるために,コンピ ュータの専門用語を用いる ・ヒューリスティック ・ブルートフォース ・ナイーブソリューション
第Ⅱ部 ループとロジックの単純化
第7 章 制御フローを読みやすく
制御フローを読みやすく 制御フロー = 条件式やループ →制御フローがないor 自然なコードは読みやすい
①条件式の引数の並び順 ②if/else のルール ③三項演算子、do/while ループ、goto ④ネストを浅くする ⑤早めに返す ⑥実行の流れを追いやすく ポイント
①条件式の引数の並び順 1-1. 条件式の引数 左:調査対象(~ はの部分) 右:比較対象 例) if(length >=10) →
◯ if(10 <= length) → × 2-1. if/else のルール ①肯定形 > 非定形 - ! はなるべく使わない ②単純な条件を先へ -if とelse が同じ画面に表示される ③目立つ条件を先へ ②if/else のルール
③三項演算子、do/while ループ、goto 3-1. 三項演算子 三項演算子は基本使わない (条件 ? a : b
) →1 行で書いた方が読みやすい 場合のみ使う 3-2. do/while ループ do/while ループは基本使わない →while ループで書く 3-3. goto goto は基本使わない →普通のループに置き換える
④ネストを浅くする 4-1. ネストを浅くする ネストの深いコードは読みにくい →1 つのネスト内に書くコードは なるべく簡潔になるようにする。 4-2. ループ内部のネストの削除 ループ内部でネストしているコー
ドは読みにくい →書き方変える/ ループを分ける。 ⑤早めに返す 5-1. 早めに返す 関数で早めに返してあげると、 ネストを削除したりコードをク リーンにしたりできる。
⑥実行の流れを追いやすく 6-1. 実行の流れを追えるか 実行の流れを追いやすいコード を書く →追うのが難しくなる構成要素 をなるべく少なくする。 例) スレッド、シグナル/ 組み込み
ハンドラ、無名関数、仮想メソ ッド 6-2. 新鮮な目で見る 変更を加えるときはコードを新 鮮な目で見る →書いている人にとっては簡潔 な変更でも初めて見た人には分 かりづらいときがある。
第8 章 巨大な式を分割する
巨大な式の分割 コードの式が大きいと理解が難しい →コードの「塊」は読みやすい大きさに分割する
①説明変数 ②要約変数 ③ド・モルガンの法則 ④短絡評価 ポイント
①説明変数 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 = ... ②要約変数
③ド・モルガン法則 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. 短略評価 短略評価: 論理演算子(&&, || )は左辺を評 価した時点で式全体の真偽値が 決定し右辺を評価する必要がな いもの →長すぎる式の場合は、変数を 使って分割する ④短絡評価
第9章 変数と読みやすさ
変数は必要な場合のみ定義する 変数のスコープはできる限り小さく する
①変数を削除する ②変数のスコープを小さくする ③変数は一度だけ書き込む ポイント
①変数を削除する 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; } }
②変数のスコープを小さく する(変数はできる限り近 くで宣言する) 2-1. グローバル変数 色々なところから値が変更され てプログラムが複雑になり、処 理の流れを追いづらくなる 問題があったときに原因が何な のか特定しづらくなる
想定外のところで値が変更され てしまう 極力使用を避ける 2-2. インスタンス変数 関数の引数で足りるデータ をインスタンス変数にしな い 加工した値をインスタンス 変数に保持しない プログラムで取得できる情 報をインスタンス変数に保 持しない 必要になったときに,使う直前で初 めて定義して、スコープを最小にす るよう心がける。 説明変数は積極的に使って良い 2-3. ローカル変数 参考:qiita 「良いコードの書き方」
③変数は一度だけ書き込む 3-1. 1度だけ書き込む 変数の値が変わると,その経過を追 跡しなければならない→読みにくい 3-2. const とfinal 可能であれば,積極的にconst や
final などのイミュータブルな宣言を 行う
第Ⅲ部 コードの再構成
第10 章 無関係の下位問題を抽出する
汎用コードを分離する プロジェクト固有のコードから汎用コードを分離
①プロジェクト固有のコードから汎用コードを分離する 理由: 1. 呼び出し側のコードが簡潔になる 2. 再利用できる 3. 改善が楽になる ②純粋なユーティリティコード -
プログラムの核となる基本的なタスクは汎用コードと して分離する 例)ファイルの読み込み、ハッシュテーブルの使用 ポイント
第11 章 一度に1 つのことを
1 つずつタスクを行うようにする 一度に複数のことをするコードは理解しにくい
①やり方 1. コードが行なっている「タスク」を全て列挙 2. タスクをできるだけ異なる関数/ クラスへ分割する ②例 ・変数への代入 ・関数の分割(1 度に1
つのことを行う) ・クラスの分割 ・ディレクトリ構成 ポイント
第12 章 コードに思いを込める
コードを書く前に,プログラムの ことを簡単な言葉で説明する ソースコードはプログラムの動作を説明する 最も大切な手段 →できる限り簡潔でわかりやすく書くべき
①ロジックを明確に説明する ②その説明に合わせてコードを書く ポイント
①ロジックを明確に説明する いきなりプログラムを書き始め るのではなく,まずは自分が実 装したいロジックを,簡潔な言 葉で説明してみる (コメントで書くのもあり) 1-2. ラバーダッキング 自分が実装しようとしていること を,アヒルのおもちゃやクマの人
形に向かって説明してみる →プログラムのを言葉にすること で,ロジックが整理され,明確な 形になる 1-1. 簡潔な言葉で説明
「権限あり/ なし」,「時間/ 銘柄/ 価 格」など,ロジックを構成する上で重要 となりそうなキーワードに着目する 2-2. 簡潔にコードを書く ロジックの説明を実装する再,難 しい/
不自然なコードではなく, 他者が読みやすいよう,できるだ け簡潔で自然なコードを書く ②説明に合わせてコードを書く 2-1. キーワードやフレーズ に注目する 2-3. ライブラリを知る 簡潔なコードを書くために,ライ ブラリが何を提供してくれてるか を知ることが欠かせない.ライブ ラリの内容を知る時間を作り,実 際に利用する
第13 章 短いコードを書く
冒険.興奮. ジェダイはそんなものを求めては おらん 新しいコードにはテストや保守が必要 →新しいコードは極力書かないようにすべき
①不必要な機能をプロダクトから削除する ②最も簡単に要求を満たす実装を考える ③コードを小さく保つ ポイント
①不必要な機能をプロダクトから 削除する 1-1. 必要機能の見積もり プロジェクトを開始するときに は,カッコいい機能のことを考 え,そしてプロダクトに書かせ ない機能を過剰に見積もりがち 1-2. 実装労力の過小評価
プログラマは, ・実装コスト ・保守/ 文章化コスト を過小評価しがち 1-3. ミニマル 不必要な機能をプロダクトから削 除する.過剰な機能は持たせな い.ミニマルなプロダクトを維持 s する
2-1. 要求の正しい評価 すべてのプログラムが,高速 で,100% 正しくて,あらゆる ケースをうまく処理できる必要 はない.どの程度の要求を満た せばいいのか,実装前に適切に 評価する 2-2.
最も簡単なプログラム 要求を正しく見積もった上で,そ の要求を満たす最もシンプルで簡 単なプログラムを実装する.難し いロジックを組む必要はない ②最も簡単に要求を満たす実装 方法を考える
3-1. ユーティリティ化 重複コードを汎用的な「ユーテ ィリティコード」にする ≒オブジェクト指向 3-2. コードの削除 「コードをせっかく書いたから, 削除したくない」そんなのどうで もいいんだよ!
未使用のコードは無用の機能はど んどん削除しよう ③コードを小さく保つ 3-3. 外部リソースの利用 - 言語の標準ライブラリ - 外部API - Unix コード を用い,コード量を減らす " たまには標準ライブラリのすべ ての関数を15 分かけて読んでみ ろ!"
(参考)平均的なソフトウェアエンジニアが 1 日に書く” 出荷用の” コードは10 行程度 →設計・デバッグ・修正・テストを生き延びるコ ードの数は多くない ⇔成熟したライブラリのコードはこの試練を生き 延びたコード
→ライブラリを使おう!!