はじめに
Factory Method を学習した際の備忘録をまとめました。
概要
オブジェクトの生成をサブクラスに委ねることで、インスタンス生成のプロセスを柔軟に設計するためのデザインパターン。クライアントコードが具体的なクラスに依存せずにオブジェクトを生成する柔軟な方法を提供する場面で有効。
利用目的
- オブジェクト生成のカプセル化
クライアント(利用者)にどの具象クラス(具体的なクラス)がインスタンス化されているかを隠し、依存性を減らす。 - インスタンス生成の柔軟性
サブクラスでオブジェクト生成のロジックを変更することができ、動的にインスタンスを変更することが可能。新しいクラスの追加が容易。新しいサブクラスを作るだけで新しいオブジェクトを生成できる。高い拡張性を持ちながら、クライアントコードが変更されずに済むことが多い。
注意点
クラスの数が増えがちで、シンプルなシステムには冗長に感じることがある。
実装
Creator.java
// Factory Methodを持つ抽象クラス
abstract class Creator {
// サブクラスが実装するFactory Method
public abstract Product createProduct();
// 製品オブジェクトを作って使う
// 【要点!】具体的な製品・工場クラスの種類が増えても、ここを変更する必要がない!
// 別のロジッククラスで定義する場合もある。
public void doSomething() {
Product product = createProduct();
product.use();
}
}
Product.java
// 製品インタフェース
public interface Product {
void use();
}
ConcreteCreatorA.java
// 具体的な工場Aが製品Aを作る
public class ConcreteCreatorA extends Creator {
public Product createProduct() {
return new ConcreteProductA();
}
}
ConcreteCreatorB.java
// 具体的な工場Bが製品Bを作る
public class ConcreteCreatorB extends Creator {
public Product createProduct() {
return new ConcreteProductB();
}
}
ConcreteProductA.java
// 具体的な製品クラスA
public class ConcreteProductA implements Product {
public void use() {
System.out.println("Product A is used.");
}
}
ConcreteProductB.java
// 具体的な製品クラスB
public class ConcreteProductB implements Product {
public void use() {
System.out.println("Product B is used.");
}
}
App.java
// 使用例
public class App {
public static void main(String[] args) throws Exception {
Creator concreteCreatorA = new ConcreteCreatorA();
concreteCreatorA.doSomething();
Creator concreteCreatorB = new ConcreteCreatorB();
concreteCreatorB.doSomething();
}
}
