DPDesign Pattern Quest
パターン一覧/Factory Method
#02 / 23
C生成DIFF

ファクトリメソッド

Factory Method

『何を作るか』はサブクラスにお任せ。注文を受け付ける本部と、実際に作る各支店の関係。

Intent · 目的

オブジェクトを生成するための『窓口メソッド』だけ親が用意して、中身を作るのはサブクラスに任せる。利用側は「Notification を作って送って」しか言わない ── Email か Slack か LINE かは、現場(サブクラス)が決める。

Motivation · 動機

ある日「通知をメールで送りたい」と書いた `new EmailNotification()`。翌週には Slack も追加。月末には LINE も。気づくと利用側コードのあちこちで `if (channel == ...) new ...()` の分岐が増殖している。生成を抽象メソッド1つに切り出せば、利用側は『誰が作られるか』を知らずに済み、新しい通知方式の追加はクラス1個足すだけで終わる。

適用場面

  • 1クライアントは生成対象の具象型を知らなくてよい場合(プラグイン的に種類を増やしたい)。
  • 2利用側コードを変えずに、生成する種類だけ差し替えたい場合。
  • 3フレームワーク側で骨組みを提供し、利用者には『生成の仕方だけ』を埋めさせたい場合。

概念図

サンプルコード

interface Notification { send(msg: string): void; }

class EmailNotification implements Notification {
  send(msg: string) { console.log(`Email: ${msg}`); }
}
class SlackNotification implements Notification {
  send(msg: string) { console.log(`Slack: ${msg}`); }
}

abstract class NotificationCreator {
  abstract create(): Notification;
  notify(msg: string) { this.create().send(msg); }
}

class EmailCreator extends NotificationCreator {
  create() { return new EmailNotification(); }
}
class SlackCreator extends NotificationCreator {
  create() { return new SlackNotification(); }
}

new SlackCreator().notify("デプロイ完了");
Pros · メリット
  • 生成と利用が分離され、利用側は具象型の存在すら知らずに済む。
  • 『新方式の追加で利用側を触らない』が成立する ── オープン・クローズドの原則の優等生。
  • テスト時にダミーやスタブのファクトリを差し込みやすく、依存の差し替えが楽。
Cons · デメリット
  • Creator のサブクラスがどんどん増え、クラス図が縦に伸びる。
  • 種類が爆発するとファクトリも爆発する。『分岐の数』を『クラスの数』に置き換えただけになる罠。
  • 1種類しかないのに先回りして導入すると、ただの遠回りなコードになる。

関連パターン

⚔ ready to test

理解度を確かめる時間だ

3 問のクイズで、 このパターンを身体に染み込ませよう。

挑戦する →