この記事ではAbstract Factoryについてまとめます。
wikipediaによると「関連する一連のインスタンスを状況に応じて、適切に生成する方法を提供する。」とあります。
参考:デザインパターン(ソフトウェア)
以下の記事を参考にさせていただきました。
沈思黙考:デザインパターン(Abstract Factory パターン)
GoFのデザインパターンをJavaで実装して理解する Abstract Factory編
1つのクラスから他クラスのメソッドを利用する場合、staticクラスを除いて「new クラス名()」というインスタンス化が必要です。このデザインパターンでは呼び出し元クラスにnewしていたものを、Factoryというクラス群にインスタンス生成部分を移動して、Factoryクラスが保持するメソッド経由で利用したいクラスのインスタンスを取得します。
実装例
ガソリンスタンドでハイオクとレギュラーを給油するケースをAbstract Factoryで表現します。
NO | ファイル名 | クラス内容 |
---|---|---|
1 | AbstractFactory.java | ガソリンを給油することを定義した抽象クラス |
2 | ConcreteHighFactory.java | ハイオクを給油する具象クラス |
3 | ConcreteRegularFactory.java | レギュラーを給油する具象クラス |
4 | AbstractRefueling.java | 給油抽象クラス |
5 | ConcreteHighRefueling.java | ハイオク給油具象クラス |
6 | ConcreteRegularRefueling.java | レギュラー給油具象クラス |
7 | Main.java | 実行するクラス |
Java
public abstract AbstractFactory {
abstract AbstractRefueling getAbstractRefueling();
}
public class ConcreteHighFactory extends AbstractFactory {
@Override
public AbstractRefueling getAbstractRefueling();
return new ConcreteHighRefueling();
}
}
public class ConcreteRegularFactory extends AbstractFactory {
@Override
public AbstractRefueling getAbstractRefueling();
return new ConcreteRegularRefueling();
}
}
public abstract class AbstractRefueling {
abstract payment();
abstract refueling();
}
public class ConcreteHighRefueling extends AbstractRefueling {
@Override
public payment() {};
@Override
public refueling() {};
}
public class ConcreteRegularRefueling extends AbstractRefueling {
@Override
public payment() {};
@Override
public refueling() {};
}
public class Main {
public static void main(String... args) {
Factory fa = exec("High");
AbstractRefueling ab = fa.getAbstractRefueling();
}
private static Factory exec(String env) {
if (env == "high") {
return new ConcreteHighFactory();
} else if (env == "regular") {
return new ConcreteRegularFactory();
}
}
}
以上のように、Mainメソッド上でハイオクガソリンを入れることを想定して、ハイオクガソリンを給油するクラスを受け取っています。必要であれば、Main.java内のexecメソッドにあるConclete〜Factoryを書き換えることでFactoryクラスで定義した他の機能に差し替えることができます。また今回のケースではハイオク、レギュラーの2種類を実装しましたが、軽油など処理の種類を追加する必要が出た場合は、抽象化できているため単純にクラスを追加するのみで済み、既存のハイオクやレギュラーのクラスに影響が少ないと言えます。しかし、クラスの追加には柔軟に対応できますが部品を追加する場合(この例では給油メソッドに加えて窓拭きメソッドを追加するなど)、影響範囲が全てのFactoryクラスに広がります。