FactoryパターンとBuilderパターンの違い
FactoryパターンとBuilderパターンは、どちらも「オブジェクト生成」を扱うデザインパターンです。
ただし、解決したい問題が違います。
| 観点 | Factoryパターン | Builderパターン |
|---|---|---|
| 主な目的 | どの具象クラスを作るかを呼び出し側から隠す | 複雑なオブジェクトを段階的に組み立てる |
| 注目点 | 生成する「種類」の切り替え | 生成する「手順」や「構成」の管理 |
| 向いている場面 | 条件によって作るクラスが変わる | コンストラクタ引数が多い、任意項目が多い |
| 呼び出し側が知ること | Factoryに依頼すればProductが返る | Builderに必要な設定を渡して最後にbuildする |
| 代表的な戻り値 | 抽象型、インターフェース、親クラス | 完成した複雑なオブジェクト |
Factoryパターン
Factoryパターンは、オブジェクト生成処理をFactoryに集約します。
呼び出し側は new ConcreteProduct() を直接書かず、Factoryに生成を依頼します。
UML記号の凡例
クラス図の中に、凡例用のクラスと矢印を入れています。
クラス図の矢印は、基本的に「知っている側・使う側」から「知られている側・使われる側」へ向けています。
たとえばFactoryは具象Productを生成するため、ProductFactory ..> ConcreteProductA の向きになります。
シーケンス図では、次の記号を使っています。
| 記号 | 意味 | このドキュメントでの読み方 |
|---|---|---|
A ->> B |
メッセージ |
A が B の処理を呼び出す |
A -->> B |
戻りメッセージ |
A が B に結果を返す |
participant A as B |
参加者の別名 | 図では B と表示し、コード上の名前は A として扱う |
クラス図
生成の流れ
Factoryのポイント
- 呼び出し側は具象クラスを知らなくてよい
- 生成条件をFactoryに閉じ込められる
- 新しい種類のProductを追加しやすい
- 「どのクラスを作るか」が主な関心事になる
Builderパターン
Builderパターンは、複雑なオブジェクトの組み立て手順をBuilderに分離します。
呼び出し側は必要な値を段階的に設定し、最後に build() で完成品を受け取ります。
クラス図
生成の流れ
Builderのポイント
- 複雑な生成手順を読みやすくできる
- 必須項目と任意項目を整理しやすい
- コンストラクタ引数が増えすぎる問題を避けやすい
- 「どう組み立てるか」が主な関心事になる
違いを一言で言うと
Factoryパターンは「どのオブジェクトを作るか」をFactoryに任せるパターンです。
Builderパターンは「どのような手順・設定でオブジェクトを作るか」をBuilderに任せるパターンです。
例で考える
Factoryが向いている例
Payment payment = PaymentFactory.create("creditCard");
payment.pay(1000);
creditCard、bankTransfer、paypal のように、条件によって作る支払い方法クラスが変わる場合に向いています。
Builderが向いている例
User user = new UserBuilder()
.name("Taro")
.email("taro@example.com")
.age(30)
.newsletterEnabled(true)
.build();
User のように項目が多く、任意設定もあるオブジェクトを読みやすく作りたい場合に向いています。
使い分けの目安
- 作る対象の種類を切り替えたいならFactory
- 1つの対象を細かく設定して作りたいならBuilder
- 生成処理の分岐が増えてきたらFactoryを検討する
- コンストラクタ引数が多くなってきたらBuilderを検討する
- 両方を組み合わせることもある
たとえば、Factoryで適切なBuilderを選び、そのBuilderで複雑なProductを作る設計も可能です。