コード探偵ロックの事件簿、全72話の案内板です。GoF のデザインパターンからリファクタリング、DDD、分散システムの障害対策まで、手元のコードの困りごとから読む話を探せます。実装は Perl と Moo です。
GoF のデザインパターン23種を、困ったコードを直す話として1話ずつ解説する全23話の目次です。実装は Perl です。
割引ルールの文字列を eval で実行していたら、セキュリティ監査でコードインジェクションと判定された。ルールを小さな式のオブジェクトに分けて構文木を組み、eval を使わずに評価する(Interpreter)。
ref() で型を判定する if-elsif が 3 つの関数に散らばり、扱う種類を1つ足すたびに全部を直すことになる。操作をクラスとして外に出し、各データには受け口を1つだけ持たせる(Visitor)。
ファイルを cp でバックアップしていたら、どれがいつの時点か分からず、一番良かった設定に戻せなくなった。状態を深いコピーでラベル付きのスナップショットにし、履歴から任意の時点へ戻す(Memento)。
モジュール同士が直接呼び合っていて、デリバリー対応を1つ足すだけで既存の全ファイルを直すことになる。やり取りの経路を仲介クラス1つに集め、各モジュールは仲介役とだけ話す(Mediator)。
調理工程を真偽値フラグ数本で管理していたら、茹で中なのに盛り付けが始まる組み合わせが生まれた。状態ごとにクラスを作り、その状態で許される操作と次の遷移先だけを書く(State)。
監視スクリプトの if-elsif にアラート種別を足すたびに、関係ない閾値判定が狂って深夜に誤報が鳴る。判定を担当ごとのハンドラに分け、順につないで次へ渡す(Chain of Responsibility)。
停止・バックアップ・更新・起動を1つの eval に並べたデプロイスクリプトは、途中で失敗すると手で戻すしかない。操作をオブジェクトにして履歴に積み、失敗したら逆順に取り消す(Command)。
SaaS の API からページを全部たどって配列に詰め込み、メモリが尽きてプロセスが落とされる。ページ送りの状態を内側に隠し、呼び出し側には1件ずつ渡す(Iterator)。
状態の変化を知るために問い合わせを繰り返し、相手のサーバーに負荷をかけ、通知先も直書きで増やせない。変化した側から登録済みの受け手へ一斉に知らせる形に変える(Observer)。
流れがほぼ同じ申請処理を 10 個のモジュールにコピーしていて、1 か所の修正を 10 回繰り返し、写し漏れで承認が二重に走った。処理の流れを親クラスに置き、違うステップだけ子クラスで書く(Template Method)。
ディスパッチテーブルで分けたはずのアルゴリズムが共有変数でつながっていて、1つ足すと別の結果まで狂う。アルゴリズムごとにクラスを分けて共有状態を断つ(Strategy)。
1 本 0.3ms のクエリなのに、同じデータをあちこちで取り直していて DB の CPU が張り付く。本体の前に代理のオブジェクトを置き、結果のキャッシュとテスト用の差し替えを1か所で受け持つ(Proxy)。