コード探偵ロックの事件簿:商品カテゴリごとにサブクラスを作り、13個になったところへ来期は20カテゴリの追加が決まった。中身は値が違うだけで構造は同じ。カテゴリをクラスではなくデータ(YAML)で表し、違う振る舞いだけを差し込む(Type Object)。
コード探偵ロックの事件簿:与信審査の閾値を700から650に変えたとき、12か所に散らばった if のうち3か所を直し漏れ、正規の顧客がローンを組めなくなった。条件をクラスにまとめ、AND・OR・NOT で組み合わせる(Specification)。
コード探偵ロックの事件簿:依存をすべてコンストラクタで渡すようにしたら、通知プラグインを1つ足すたびにコンストラクタの引数とテストを全部直すことになった。プラグインはレジストリに登録し、そのレジストリだけを注入する(Registry と DI の併用)。
コード探偵ロックの事件簿:CI を入れたら、ローカルでは通るテストが全部落ちた。原因はクラスの中で CSV の読み込みや SMTP 送信の部品を直接 new していたこと。部品はコンストラクタで受け取り、組み立ては1か所にまとめる(Dependency Injection)。
コード探偵ロックの事件簿:共通のサービスをグローバルなレジストリから取り出していたため、テストどうしが状態を共有し、実行順によって18件中4〜7件が落ちる。必要な依存はコンストラクタで受け取り、足りなければ生成時に気づけるようにする(Service Locator の撤去)。
コード探偵ロックの事件簿:init・configure・start の順に呼ばないと動かないクラスで、configure を飛ばす事故。必須の値を required と BUILD で強制する(Temporal Coupling の解消)。
コード探偵ロックの事件簿:決済のステータス更新が反映されない原因は、文字列 'actve' の1文字抜けだった。数値や文字列を直に書かず、use constant で名前を付け、Type::Tiny の Enum でコンストラクタ時に弾く(Magic Numbers / Strings)。
コード探偵ロックの事件簿:コメントアウトの旧ロジックや if (0) が「消すと壊れるかも」で残り続ける。カバレッジを測って根拠を持ち、段階的に消す(Dead Code / Lava Flow)。
コード探偵ロックの事件簿:基底クラスを継承した CreditNote が、合わない validate を die で潰していた。継承をやめ、必要な能力だけをロールと委譲で持たせる(Composition over Inheritance)。
コード探偵ロックの事件簿:メソッドチェーンをなくすために委譲を全クラスへ広げたら、中身のない転送メソッドだけを並べたクラスが生まれた。意味のない仲介役を外し、委譲する場所と直接呼ぶ場所を見直す(Remove Middle Man)。
コード探偵ロックの事件簿:住所のカラム名を変えただけで、メソッドチェーンでたどっていた配送料・税・請求書の計算が同時に例外で落ちた。中間のオブジェクトをたどらず、Moo の handles で直接聞ける形にする(Law of Demeter)。
コード探偵ロックの事件簿:レポート生成のメソッドが他クラスのゲッターばかり呼び、機能を足すたびにテストが壊れる。メソッドをデータの持ち主へ移す(Feature Envy の解消)。
コード探偵ロックの事件簿:注文・在庫・支払いを別々に書き込んでいたため、途中で失敗すると注文だけが残り、13週続けて手で直していた。変更をすべて1つのオブジェクトに登録し、commit でまとめて反映、失敗したら全部取り消す(Unit of Work)。
コード探偵ロックの事件簿:受注の書き込みとダッシュボードの集計が1つのリポジトリに同居し、バリデーションを直すと集計のテストが落ち、集計を直すと受注が落ちる。書き込み(Command)と読み取り(Query)を別のクラスに分ける(CQRS)。
コード探偵ロックの事件簿:在庫数を直接上書きしていたため、監査部門から過去30日間の入出荷の根拠を求められても、今の数しか分からない。入荷・出荷を出来事として追記し、在庫数は出来事を再生して求める(Event Sourcing)。任意の時点の在庫も計算できます。