バーのカウンターで、コードの相談を聞く連載です。「15か所に同じ数字が書いてあって、直すのに2日かかった」「メール欄に電話番号が入っていた」「テストを書くたびに、モックの登録とリセットが要る」。持ち込まれた困りごとを、バーテンダーが「コードのにおい(コードスメル)」として見立て、リファクタリングで直すまでを全12話でたどります。
どの話からでも読めます。実装は Perl と Moo ですが、コードを書ける必要はありません。直す前と後のコードを見比べて、何が変わったかを追えれば十分です。
このページは目次を兼ねた案内板です。初めてなら「まず読むなら」の3本から、手元に困っているコードがあるなら「困りごとから探す」から選んでください。
まず読むなら
- Magic Numbers — if 文の中の 36 や 3600 が何の値か分からない回。どのコードにも潜む困りごとで、シリーズの出発点になる
- Shotgun Surgery — 税率の0.08が15か所に散らばり、1か所直すと他でテストが壊れる回。仕様変更のたびに何か所も開く現場なら、いちばん効く
- Service Locator — 依存の取り出しが隠れていて、テストの準備に手順書が要る回。テストを書きにくいコードを抱えているなら、そのまま当てはまる
困りごとから探す
直すたびに、関係ないはずの所まで壊れる
- Feature Envy — 他のクラスのデータばかり触るメソッドが、相手の変更で壊れる
- Law of Demeter — 注文から顧客、住所と -> でたどり、中間のクラスを変えると壊れる
- Shotgun Surgery — 同じ数字が15か所にあり、1か所の変更が全体に波及する
- God Class — 1つのクラスが何でも抱え込み、どの変更もそこに流れ込む
意味が読み取れない、取り違えても気づけない
- Magic Numbers — 裸の数値が何を指すのか分からない
- Primitive Obsession — メール欄に電話番号が入っても、エラーにならない
- Temporal Coupling — init() を先に呼ぶ決まりが、手順書にしか書かれていない
使われていない、役目のないコードが残っている
- Dead Code — 前任者の古いメソッドが、怖くて消せない
- Speculative Generality — 実装が1つしかない抽象クラスや、一度も使わないオプションが残っている
- Middle Man — 全メソッドを転送するだけのクラスが、間に挟まっている
継承や依存の組み方が合っていない
- Refused Bequest — 親のメソッドを die や空で拒否している
- Service Locator — 依存がコンストラクタに現れず、テストが書きにくい
全話一覧
- if 文に 36 と 72 と 3600 が並び、書いた先輩はもういない。裸の数値に名前を付ける【Magic Numbers】
- レポート生成メソッドが $order-> だらけで、Order の変更のたびに壊れる。処理をデータのある側へ移す【Feature Envy】
- 前任者の3年前のコードが怖くて消せない。呼び出し元を確かめて、段階的に削除する【Dead Code】
- 継承した save と delete を die で潰し、update は空にした。継承をやめて必要な性質だけ受け取る【Refused Bequest】
- OrderManager を通す決まりで、メソッドが全部ただの転送になった。間の一段を外して直接呼ぶ【Middle Man】
- メールアドレス欄に電話番号が入り、金額は文字列のまま足されて桁がずれる。値を専用の型にする【Primitive Obsession】
- init() を先に呼ぶ手順を飛ばされて、本番が落ちた。呼ぶ順番をコードの型で縛る【Temporal Coupling】
- 注文から顧客、住所、都市名まで -> でたどる。Customer を直したら周りも全部壊れる【Law of Demeter】
- テストのたびにモックを登録してリセットする。ServiceLocator をやめ、依存をコンストラクタで受け取る【Service Locator】
- 実装が1つしかない抽象クラスと、一度も使わないオプションが残っている。将来のための設計を消す【Speculative Generality】
- 消費税率を直すだけで15ファイルを開く羽目になった。税率を1つのクラスに集める【Shotgun Surgery】
- あらゆる処理を1つのクラスが抱え込み、直すたびに全体が揺れる。責務ごとに分けて委譲する【God Class】
