@nqounetです。
いよいよ最終回です。これまで作ってきたAPIレスポンスシミュレーターの設計が、実は「Factory Methodパターン」というデザインパターンであることを明かします。
このシリーズについて
シリーズ全体の目次は以下をご覧ください。
シリーズの振り返り
8回を通じて、以下のように設計を進化させてきました:
- 第1回: シンプルなMockApiを作る(基底クラスでの生成)
- 第2回: シナリオが増えてif/elseが肥大化(問題の認識)
- 第3回: シナリオごとにクラスを分ける(継承によるCreator分離)
- 第4回: Roleで共通インターフェースを定義(Productインターフェース)
- 第5回: 生成処理をオーバーライド(Factory Methodのオーバーライド)
- 第6回: 共通処理を基底クラスに集約(共通処理の集約)
- 第7回: 新しいシナリオを追加してOCPを体験(オープン・クローズドの原則)
この段階的な設計改善こそが、Factory Methodパターンを自然に習得するための道のりでした。そして今回、この設計パターンに名前がついていることをお伝えします。
Factory Methodパターンとは
GoF(Gang of Four)のデザインパターンの1つで、以下のように定義されています:
オブジェクトを生成するためのインターフェースを定義し、どのクラスをインスタンス化するかはサブクラスに決定させる。Factory Methodは、インスタンス化をサブクラスに委ねる。
難しく聞こえますが、私たちが作ったものそのものです。
構造の対応関係
Factory Methodパターンの登場人物と、私たちの実装を対応させてみましょう。
| Factory Method用語 | 私たちの実装 | 役割 |
|---|---|---|
| Product | ResponseRole | 生成されるオブジェクトのインターフェース |
| ConcreteProduct | SuccessResponse, ErrorResponse, RateLimitResponse | 実際に生成されるオブジェクト |
| Creator | Scenario | factory method(create_response)を宣言する抽象クラス |
| ConcreteCreator | SuccessScenario, NotFoundScenario, RateLimitScenario | factory methodを実装する具象クラス |
クラス図で確認する
classDiagram
class ResponseRole {
<<interface>>
+render() String
}
class SuccessResponse {
+data
+render() String
}
class ErrorResponse {
+status
+error_code
+message
+render() String
}
class RateLimitResponse {
+retry_after
+render() String
}
class Scenario {
+create_response() Response
+execute() String
}
class SuccessScenario {
+create_response() SuccessResponse
}
class NotFoundScenario {
+create_response() ErrorResponse
}
class RateLimitScenario {
+retry_after
+create_response() RateLimitResponse
}
ResponseRole <|.. SuccessResponse
ResponseRole <|.. ErrorResponse
ResponseRole <|.. RateLimitResponse
Scenario <|-- SuccessScenario
Scenario <|-- NotFoundScenario
Scenario <|-- RateLimitScenario
SuccessScenario ..> SuccessResponse : creates
NotFoundScenario ..> ErrorResponse : creates
RateLimitScenario ..> RateLimitResponse : creates
Factory Methodのメリット
このパターンを使うことで得られるメリットを整理しましょう:
- 生成処理の分離: オブジェクトの生成と使用を分離できる
- 拡張性: 新しい種類のオブジェクトを追加しやすい(OCP)
- 一貫性: 共通処理を基底クラスで保証できる
- テスト容易性: 各Creatorを独立してテストできる
Factory Methodの適用場面
以下のような場面でFactory Methodが有効です:
- どのクラスを生成するかが実行時まで決まらない
- サブクラスで生成するオブジェクトを決定したい
- 生成処理を局所化して、変更の影響範囲を限定したい
完成コード
シリーズ全体の完成コードを1ファイルにまとめると、以下のようになります。
| |
まとめ
全8回を通じて、if/elseの肥大化問題をFactory Methodパターンで解決する過程を体験しました:
- 問題の認識: シナリオが増えると条件分岐が爆発する
- 継承による分離: シナリオごとにクラスを分ける
- インターフェースの定義: Roleで共通ルールを強制
- 共通処理の集約: 基底クラスにロジックをまとめる
- OCPの実践: 既存コードを修正せずに拡張
Factory Methodは、オブジェクトの生成を柔軟に行いたい場面で強力なパターンです。ぜひ実際の開発でも活用してみてください。

