1. パターンの意図
ファクトリーメソッド(Factory Method) は、オブジェクト生成の手順をサブクラスに委譲する デザインパターンです。
解決する問題
- 生成するオブジェクトの型を 実行時に切り替えたい
-
new
を直接使うと 依存関係が強くなり拡張に弱い - インスタンス化ロジックを一元管理したい
ポイント
- 生成方法を抽象化し、利用側は「何を作るか」ではなく「どう使うか」に集中できる
- 新しい製品クラスを追加しても、クライアントコードを変更せず拡張できる
2. UML 図
3. Flutter / Dart 実装例
3.1 プロダクトの抽象クラス
abstract class ApiClient {
void request(String endpoint);
}
class RestApiClient extends ApiClient {
@override
void request(String endpoint) {
print("REST API request: $endpoint");
}
}
class GraphQLApiClient extends ApiClient {
@override
void request(String endpoint) {
print("GraphQL API request: $endpoint");
}
}
3.2 ファクトリーメソッド
abstract class ApiClientFactory {
ApiClient createClient();
}
class RestApiClientFactory implements ApiClientFactory {
@override
ApiClient createClient() => RestApiClient();
}
class GraphQLApiClientFactory implements ApiClientFactory {
@override
ApiClient createClient() => GraphQLApiClient();
}
3.3 利用例
void main() {
ApiClientFactory factory = RestApiClientFactory();
var client = factory.createClient();
client.request("/users");
factory = GraphQLApiClientFactory();
client = factory.createClient();
client.request("{ users { id name } }");
}
4. Android / Kotlin 実装例
4.1 プロダクトの抽象クラス
interface ApiClient {
fun request(endpoint: String)
}
class RestApiClient : ApiClient {
override fun request(endpoint: String) {
println("REST call → $endpoint")
}
}
class GraphQLApiClient : ApiClient {
override fun request(endpoint: String) {
println("GraphQL query → $endpoint")
}
}
4.2 ファクトリーメソッド
abstract class ApiClientFactory {
abstract fun createClient(): ApiClient
}
class RestApiClientFactory : ApiClientFactory() {
override fun createClient(): ApiClient = RestApiClient()
}
class GraphQLApiClientFactory : ApiClientFactory() {
override fun createClient(): ApiClient = GraphQLApiClient()
}
4.3 利用例
fun main() {
var factory: ApiClientFactory = RestApiClientFactory()
var client = factory.createClient()
client.request("/users")
factory = GraphQLApiClientFactory()
client = factory.createClient()
client.request("{ users { id name } }")
}
5. メリット / デメリット
メリット
- 新しい製品クラスを追加してもクライアントを変更しなくて良い
- 依存関係が緩和され、拡張性が高い
- 生成処理を一元管理できる
デメリット
- クラス階層が増える
- 小規模プロジェクトでは冗長になりがち
6. 実務ユースケース
Flutter
- API クライアント切替(REST / GraphQL / gRPC)
- データストレージ切替(ローカル / リモート)
- UI コンポーネント生成(テーマ別ボタンや入力欄)
Android (Kotlin)
- Retrofit クライアントの生成切替
- Repository 層でのデータソース選択(DB / ネットワーク)
- Factory パターンで ViewModel インスタンスを提供
7. 実装上の注意点
Flutter / Dart
-
シングルトン + ファクトリ を組み合わせると便利
- 例:
ApiClientFactory
自体をシングルトンにして環境設定で切替
- 例:
-
abstract factory
と混同しやすいが、- Factory Method → 1つの製品生成に特化
- Abstract Factory → 一連の関連製品群をまとめて生成
Android / Kotlin
-
sealed class
と組み合わせると 分岐を閉じ込められる - Hilt などの DI フレームワークで ファクトリーメソッドを Provider として登録 するのが実務的
8. どんなときに使う?
- API やデータソースが環境によって変わる
- 同じインターフェースで複数実装を切替たい
- 生成ロジックを一元管理して拡張性を確保したい
まとめ
- ファクトリーメソッドは 生成をサブクラスに委譲する仕組み
- Flutter/Android 開発では API クライアントやデータソース切替 に多用される
- 小規模では冗長だが、中〜大規模では保守性・拡張性を飛躍的に高める
- 実務では DIコンテナと組み合わせて利用 するのがベストプラクティス