コード探偵ロックの事件簿:決済完了時の通知がメール・SMS・Slack・Push と増え、そのたびに OrderService の中で通知クラスを new する分岐を足していた。生成を工場クラスに移し、注文処理は工場に頼むだけにする(Factory Method)。テストではダミーの工場を渡せます。
コード探偵ロックの事件簿:別チームのクラスの内部ハッシュを直接読んでいたため、キー名が変わっただけでレポート API が全滅した。代理人を挟み、アクセスをそこだけに通す(Proxy)。
コード探偵ロックの事件簿:IP 制限・認証・権限チェックを1つのメソッドの if に詰め込み、トークンの期限を変えただけで全 API が落ちた。チェックごとに分けて鎖でつなぐ(Chain of Responsibility)。
コード探偵ロックの事件簿:注文処理が途中で失敗したとき、DB はロールバックできても外部の決済 API の課金は戻らず、お金だけ受け取って注文はキャンセルされる。操作を実行と取り消しの対を持つオブジェクトにし、失敗したら逆順に取り消す(Command)。
コード探偵ロックの事件簿:配送ロボットの受注システムで、1つのクラスが決済・在庫・配送・通知のサブシステムを直接操作し、仕様を1つ変えたらエラーが連鎖した。サブシステムの前に窓口のクラスを1つ置き、呼び出し側はそこだけを使う(Facade)。
コード探偵ロックの事件簿:引数10個の関数が5階層続き、途中で user_id と shop_id の順番が入れ替わった。どちらも数値でエラーにならない。一緒に渡る引数を1つにまとめる(Parameter Object)。
コード探偵ロックの事件簿:どこからでも呼べる Singleton の DB 接続を使い回し、並列の夜間バッチでテストのつもりの処理が本番 DB を書き換えた。接続をコンストラクタで受け取る(Dependency Injection)。
コード探偵ロックの事件簿:データだけの Order と、計算を抱える数千行の OrderService。割引ルールが増えるたびに Service のあちこちを直す。計算を Order 自身にさせる(Tell, Don't Ask)。
コード探偵ロックの事件簿:年齢や電話番号を Perl の素のスカラーで持ち、ログ出力で文字列結合しただけで JSON の型が変わる。年齢が文字列になり、電話番号の先頭の0が消えた。値を専用のクラスに包み、出力の形もそこで決める(Value Object)。
コード探偵ロックの事件簿:注文の状態を 0・1・2・3 の数字で持ち、支払い・発送・キャンセルの処理がすべて if-elsif で状態を確かめる。条件が絡み、発送済みの注文にキャンセルが通った。状態ごとのクラスに振る舞いを任せる(State)。
コード探偵ロックの事件簿:ポイント付与にログ・メール通知・2倍キャンペーンを継承で足していったら、機能3つでクラスが8個、4つ目で16個に増える。本体を同じインターフェースの包みで重ね、機能を外から足す(Decorator)。
コード探偵ロックの事件簿:在庫を更新する1つのメソッドにメール通知・ログ・ダッシュボード更新が詰め込まれ、1か所直すと別の機能が止まる。在庫の変化を通知にして、受け手がそれぞれ反応する形に分ける(Observer)。
コード探偵ロックの事件簿:2つの CSV エクスポートが、データ取得・ヘッダー生成・行の整形・出力の結合という同じ手順をコピペで持ち、バグ修正も二重になる。手順の骨格を親クラスに置き、違う部分だけをサブクラスに書く(Template Method)。
コード探偵ロックの事件簿:5000行のメソッドが CSV・JSON・XML の出力をすべて if-elsif で抱え、YAML を足すにもそこへ書き足すしかない。形式ごとの処理をクラスに分け、外から差し替える(Strategy)。Perl と Moo で実装します。