Featured image of post コード探偵ロックの事件簿 連載目次【困りごとから探す案内板】

コード探偵ロックの事件簿 連載目次【困りごとから探す案内板】

コード探偵ロックの事件簿、全72話の案内板です。GoF のデザインパターンからリファクタリング、DDD、分散システムの障害対策まで、手元のコードの困りごとから読む話を探せます。実装は Perl と Moo です。

「コード探偵ロックの事件簿」は、困ったコードを抱えた依頼人が、雑居ビルの一室にある「レガシー・コード・インベスティゲーション(LCI)」に駆け込む連載です。自称コード探偵のロックが、依頼人を勝手に「ワトソン君」と呼びながら、コードに残った証拠から原因を割り出し、設計の技法を使って直します。

全72話で、GoF のデザインパターンから、リファクタリングの技法、DDD(ドメイン駆動設計)、分散システムの障害対策までをたどります。どの話からでも読めます。実装は Perl と Moo ですが、直す前と後のコードを見比べて、何が変わったかを追えれば十分です。

このページは目次を兼ねた案内板です。初めてなら「まず読むなら」の3本から、手元に困っているコードがあるなら「困りごとから探す」から、順に通して読むなら「全話一覧」から選んでください。

まず読むなら

  • Strategy — 形式を足すたびに巨大な if-elsif へ書き足している回。連載の第1話で、ほかの話を読む足場になる
  • Dependency Injection — ローカルでは通るテストが CI で全部落ちる回。クラスの中の new を外へ出すだけで、明日からのテストが書きやすくなる
  • Circuit Breaker — 外部 API の障害でリトライを増やすほど停止が長引く回。ここから5話、同じ依頼人の現場で障害対策を1つずつ積み上げていく

困りごとから探す

条件分岐が伸び続けて、足すたびにどこかが壊れる

  • Strategy — 出力形式ごとに分岐する5000行のメソッド
  • State — 0〜3の数字で持つ注文の状態
  • State — ステータスを足したら無関係な処理が壊れる状態遷移
  • Chain of Responsibility — 認証や権限チェックを詰め込んだ if のネスト
  • Composite — 「タスクかグループか」を全関数で判定している
  • Visitor — 型判定の分岐を1か所書き忘れた
  • Double Dispatch — 帳票と出力形式の組み合わせで書き忘れた
  • Specification — 同じ条件が12か所の if に散らばっている
  • Plugin — チャネルを足すたびにコアの if-elsif を書き換える

組み合わせの数だけ、クラスやコピペが増える

  • Template Method — 手順が同じ処理を丸ごとコピーしている
  • Decorator — 機能の組み合わせごとに継承でクラスを作っている
  • Decorator — 通知のサブクラスが30個を超えた
  • Bridge — 文書の種類×出力形式でクラスが掛け算に増える
  • Prototype — 似た帳票を毎回ゼロから組み立てている
  • Abstract Factory — セットで使う部品の組み合わせが混ざる
  • Type Object — 値が違うだけのサブクラスが並んでいる

1か所直すと、関係ないはずの所が壊れる

  • Observer — 1つのメソッドが通知もログも画面更新も呼んでいる
  • Domain Event — 処理を足したら、別の処理が二重に走った
  • Facade — 1つのクラスが全サブシステムを直接呼んでいる
  • Mediator — モジュール同士が直接呼び合っている
  • Proxy — 他チームのクラスの内部データを直接読んでいる
  • Law of Demeter — メソッドチェーンの奥でカラム名の変更に巻き込まれた
  • Feature Envy — 自分のデータを使わず、他クラスのデータばかり触っている
  • Tell, Don’t Ask — 計算をすべて Service クラスが抱えている
  • CQRS — 書き込みを直すと集計が落ち、集計を直すと書き込みが落ちる
  • Bounded Context — 部門ごとに意味の違う顧客を1つのモデルにまとめた
  • Pipeline — 全処理が500行のメソッドに詰まっている
  • Iterator — 内部構造をたどるスクリプトが構造の変更で全滅した

値の取り違えやチェック漏れで、本番が落ちる

テストが遅い、CI で落ちる、差し替えられない

  • Repository — DB が要るテストに30分かかる
  • Singleton/DI — どこからでも呼べる DB 接続のせいでテストが本番を触った
  • Service Locator — テストどうしが状態を共有して、毎日数件落ちる
  • Dependency Injection — クラスの中で部品を new している
  • Registry — プラグインを足すたびにコンストラクタとテストを直す
  • Factory Method — 通知手段を足すたびに本体の new を書き換える

データが食い違う、元に戻せない

  • Command — DB は戻せても外部 API の操作は戻せない
  • Memento — 上書きした状態を前に戻せない
  • Unit of Work — 複数のテーブルへの書き込みが途中で止まる
  • Aggregate — 合計金額と明細が合わない
  • Event Sourcing — 過去の時点の数が分からない
  • Saga — サービスをまたぐ処理を途中で取り消せない
  • Outbox — DB は更新できたのに通知が消えた

外部サービスの障害や負荷で、全体が止まる

  • Publish-Subscribe — 1つのサービスが落ちると呼び出し元も止まる
  • Circuit Breaker — リトライを増やすほど停止が長引く
  • Retry Pattern — 全台が同時にリトライして短い障害が長引く
  • Timeout — タイムアウトを既定値のまま放っている
  • Fallback Pattern — 代わりの経路が同じ障害の原因を叩いている
  • Rate Limiting — 通常の10倍のリクエストが来た
  • Bulkhead — 1つの機能の暴走でサイト全体が止まった
  • Health Check — ヘルスチェックは緑なのに画面が落ちている
  • Dead Letter Queue — 処理できないメッセージがキューを塞いでいる
  • Competing Consumers — 処理する台数を増やしたら二重に処理された

重い、メモリが足りない

  • Flyweight — 同じデータを件数分コピーしている
  • Object Pool — リクエストごとに DB 接続を作って捨てている
  • Lazy Loading — 起動時に使わないデータまで全部読んでいる

古いシステムや外部の仕組みとつなぐ、置き換える

  • Adapter — 新旧システムでメソッド名もデータの形も違う
  • Anti-Corruption Layer — 外部 API の項目名が社内のコードに入り込んでいる
  • Strangler Fig — 古いシステムを一斉に切り替えようとして失敗した
  • API Gateway — フロントがバックエンドの URL を全部知っている
  • Backends for Frontends — Web とモバイルで同じ API を使っている

消せない、合わない、意味のないコードが残っている

  • Dead Code / Lava Flow — 「消すと壊れるかも」で残したコード
  • Refused Bequest — 継承したのに使えないメソッドを die で潰している
  • Middle Man — 転送するだけのクラスが挟まっている

全話一覧

デザインパターンと設計の基本(第1〜27話)

コードのにおいと依存の扱い(第28〜46話)

ドメインのモデリング(第47〜54話)

分散システムと障害対策(第55〜72話)

comments powered by Disqus
システム開発・AIワークフローのご相談は Meetsource へ
Hugo で構築されています。
テーマ Stack は Jimmy によって設計されています。