はじめに
ファクトリーパターン(Factory Pattern)は、Javaのデザインパターンの中で頻繁に使用される オブジェクト生成に関するパターン です。
「どのクラスのインスタンスを生成するか」を柔軟に管理し、コードをシンプルかつ保守しやすくすることが目的です。
この記事では、ファクトリーパターンの基本概念、シンプルな実装方法、実用的なサンプルコード を初心者でも理解できるように解説します。
1. ファクトリーパターンとは?
ファクトリーパターンは、オブジェクトを直接 new
で生成する代わりに、専用の工場(Factory)メソッド でインスタンスを生成する方法です。
なぜファクトリーパターンが必要か?
- 柔軟なインスタンス生成: 生成するオブジェクトの種類を動的に切り替えられる。
- コードの依存性を減らす: 具体的なクラス名を直接書かないため、保守性が向上する。
- DRY原則: オブジェクト生成の処理を1箇所にまとめることで、コードの重複を防ぐ。
2. ファクトリーパターンの構成
ファクトリーパターンは以下の3つの要素で構成されます:
- 抽象クラス/インターフェース
- 共通のメソッドを定義する。
- 具体クラス
- 抽象クラスを実装し、具体的な動作を定義する。
- ファクトリクラス
- どの具体クラスのインスタンスを生成するかを判断する。
3. 基本的なファクトリーパターンの実装
3.1 サンプル: 動物のオブジェクトを生成する工場
「Dog」や「Cat」のオブジェクトを作成する例を使って、ファクトリーパターンを実装します。
ステップ1: 抽象クラス/インターフェースの定義
1 |
// 抽象クラスまたはインターフェース<br>interface Animal {<br> void sound(); // 共通のメソッド<br>}<br> |
ステップ2: 具体クラスの実装
1 |
// 具体クラス: 犬<br>class Dog implements Animal {<br> @Override<br> public void sound() {<br> System.out.println("ワンワン");<br> }<br>}<br><br>// 具体クラス: 猫<br>class Cat implements Animal {<br> @Override<br> public void sound() {<br> System.out.println("ニャーニャー");<br> }<br>}<br> |
ステップ3: ファクトリクラスを作成
1 |
// ファクトリクラス<br>class AnimalFactory {<br> public static Animal createAnimal(String type) {<br> if ("dog".equalsIgnoreCase(type)) {<br> return new Dog();<br> } else if ("cat".equalsIgnoreCase(type)) {<br> return new Cat();<br> } else {<br> throw new IllegalArgumentException("不明な動物タイプ: " + type);<br> }<br> }<br>}<br> |
ステップ4: ファクトリを使ってオブジェクトを生成
1 |
public class Main {<br> public static void main(String[] args) {<br> // 犬のインスタンスを生成<br> Animal dog = AnimalFactory.createAnimal("dog");<br> dog.sound(); // 出力: ワンワン<br><br> // 猫のインスタンスを生成<br> Animal cat = AnimalFactory.createAnimal("cat");<br> cat.sound(); // 出力: ニャーニャー<br> }<br>}<br> |
3.2 コードの流れ
- 抽象クラス/インターフェース:
Animal
で共通のメソッドを定義。 - 具体クラス:
Dog
とCat
がそれぞれAnimal
を実装。 - ファクトリクラス:
AnimalFactory
がAnimal
の具体的なオブジェクトを生成。 - 呼び出し側: ファクトリを使って動物のオブジェクトを生成し、共通のメソッドを呼び出す。
4. ファクトリパターンの応用例
4.1 システム設定やデータベース接続
ファクトリパターンは、設定ファイルや条件に応じて異なるデータベース接続クラスを生成する場合に利用できます。
サンプル: データベース接続クラス
1 |
// 抽象クラス/インターフェース<br>interface Database {<br> void connect();<br>}<br><br>// 具体クラス: MySQL<br>class MySQL implements Database {<br> @Override<br> public void connect() {<br> System.out.println("MySQLに接続しました。");<br> }<br>}<br><br>// 具体クラス: Oracle<br>class Oracle implements Database {<br> @Override<br> public void connect() {<br> System.out.println("Oracleに接続しました。");<br> }<br>}<br><br>// ファクトリクラス<br>class DatabaseFactory {<br> public static Database getDatabase(String dbType) {<br> if ("mysql".equalsIgnoreCase(dbType)) {<br> return new MySQL();<br> } else if ("oracle".equalsIgnoreCase(dbType)) {<br> return new Oracle();<br> }<br> throw new IllegalArgumentException("不明なデータベースタイプ: " + dbType);<br> }<br>}<br><br>// 使用例<br>public class Main {<br> public static void main(String[] args) {<br> Database db = DatabaseFactory.getDatabase("mysql");<br> db.connect(); // 出力: MySQLに接続しました。<br><br> Database db2 = DatabaseFactory.getDatabase("oracle");<br> db2.connect(); // 出力: Oracleに接続しました。<br> }<br>}<br> |
5. ファクトリパターンのメリットとデメリット
メリット
- 柔軟性: どのクラスのオブジェクトを生成するかを外部から変更可能。
- コードの依存性低減: 具体クラスを直接呼び出さず、インターフェースや抽象クラスを使うため変更に強い。
- 保守性向上: オブジェクト生成処理を1箇所にまとめることで修正が容易。
デメリット
- コードが増える: 小さなシステムでは不要に感じることもある。
- 複雑性: ファクトリが増えすぎると管理が難しくなる。
6. まとめ
ファクトリパターンは、オブジェクト生成を柔軟に管理するための強力な設計パターンです。
- 基本構成: 抽象クラス/インターフェース、具体クラス、ファクトリクラス。
- 使い方: クラスのインスタンス生成を
Factory
に任せることで、コードの柔軟性と保守性を向上させる。 - 実用例: 動物オブジェクト生成、データベース接続設定など。
初心者の方はシンプルな例から始めて、少しずつ実践の中で使い方をマスターしていきましょう。
次のステップ
デザインパターンをさらに深く学びたい方は、絶対にJavaプログラマーになりたい人へ で学習を進め、実務スキルを向上させましょう!また、転職サポートも受けたい方は サイゼントアカデミー が最適です。
コメント