Abstract Factory パターン

「Abstract Factory」という英単語は、「抽象的な工場」を意味します。

このパターンは、関連のある一連のオブジェクト郡をまとめて生成する方法を提供するパターンです。このパターンを適用すると、上記関連オブジェクトグループ単位での入替え・追加が容易に行えます。

よく似たパターンに「Factory Method」パターンがありますが、「Factory Method」パターンは、『オブジェクト生成』の抽象化にポイントを置いたパターンであるのに対し、「Abstract Factory」パターンは、『関連するオブジェクト郡をまとめて生成するための手順』の抽象化にあります。


役割り

1. AbstractProduct1・2・3(抽象的な製品)
「AbstractFactory」(抽象的な工場)によって生成される抽象的なオブジェクト(部品・製品)のインタフェースを定義します。
2. ConcreteProductA1・A2・A3、ConcreteProductB1・B2・B3(具体的な製品)
「AbstractProduct1・2・3」のインタフェースを実装します。
3. AbstractFactory(抽象的な工場)
「AbstractProduct1・2・3」を生成するためのインタフェースを定義します。
※Factoryオブジェクト「ConcreteFactoryA」「ConcreteFactoryB」(具体的な工場)を生成するためのクラスメソッドを定義します。
4. ConcreteFactoryA・ConcreteFactoryB(具体的な工場)
「AbstractFactory」のインタフェースを実装します。
5. Client(利用者)
「AbstractProduct1・2・3」「AbstractFactory」が提供するインタフェースのみを使用して処理を行います。

▲PageTop

クラス図

Abstract Factoryパターンのクラス図

Abstract Factoryパターン クラス図

▲PageTop

サンプル

ソースコード

1-1. AbstractProduct1.java

public abstract class AbstractProduct1 {
    protected String name;
    public AbstractProduct1(String name) {
        this.name = name;
    }
    public abstract void execute();
}

1-2. AbstractProduct2.java

public abstract class AbstractProduct2 {
    protected String name;
    public AbstractProduct2(String name) {
        this.name = name;
    }
    public abstract void run();
}

1-3. AbstractProduct3.java

public abstract class AbstractProduct3 {
    protected String name;
    public AbstractProduct3(String name) {
        this.name = name;
    }
    public abstract void action();
}

2-1. ConcreteProductA1.java

public class ConcreteProductA1 extends AbstractProduct1 {
    public ConcreteProductA1(String name) {
        super(name);
    }
    public void execute() {
        System.out.println(name + " 完成(A1-execute)!");
    }
}

2-2. ConcreteProductA2.java

public class ConcreteProductA2 extends AbstractProduct2 {
    public ConcreteProductA2(String name) {
        super(name);
    }
    public void run() {
        System.out.println(name + " 完成(A2-run)!");
    }
}

2-3. ConcreteProductA3.java

public class ConcreteProductA3 extends AbstractProduct3 {
    public ConcreteProductA3(String name) {
        super(name);
    }
    public void action() {
        System.out.println(name + " 完成(A3-action)!");
    }
}

2-4. ConcreteProductB1.java

public class ConcreteProductB1 extends AbstractProduct1 {
    public ConcreteProductB1(String name) {
        super(name);
    }
    public void execute() {
        System.out.println(name + " 完成(B1-execute)!");
    }
}

2-5. ConcreteProductB2.java

public class ConcreteProductB2 extends AbstractProduct2 {
    public ConcreteProductB2(String name) {
        super(name);
    }
    public void run() {
        System.out.println(name + " 完成(B2-run)!");
    }
}

2-6. ConcreteProductB3.java

public class ConcreteProductB3 extends AbstractProduct3 {
    public ConcreteProductB3(String name) {
        super(name);
    }
    public void action() {
        System.out.println(name + " 完成(B3-action)!");
    }
}

3-1. AbstractFactory.java

public abstract class AbstractFactory {
    public static AbstractFactory createFactory(int factoryId){
        switch(factoryId){
            case ConcreteFactoryA.id:
                return new ConcreteFactoryA();
            case ConcreteFactoryB.id:
                return new ConcreteFactoryB();
            default:
                return null;
        }
    }
    public abstract AbstractProduct1 createProduct1();
    public abstract AbstractProduct2 createProduct2();
    public abstract AbstractProduct3 createProduct3();
}

4-1. ConcreteFactoryA.java

public class ConcreteFactoryA extends AbstractFactory {
    public static final int id = 1;
    public AbstractProduct1 createProduct1() {
        return new ConcreteProductA1("工場A - 製品1");
    }
    public AbstractProduct2 createProduct2() {
        return new ConcreteProductA2("工場A - 製品2");
    }
    public AbstractProduct3 createProduct3() {
        return new ConcreteProductA3("工場A - 製品3");
    }
}

4-2. ConcreteFactoryB.java

public class ConcreteFactoryB extends AbstractFactory {
    public static final int id = 2;
    public AbstractProduct1 createProduct1() {
        return new ConcreteProductB1("工場B - 製品1");
    }
    public AbstractProduct2 createProduct2() {
        return new ConcreteProductB2("工場B - 製品2");
    }
    public AbstractProduct3 createProduct3() {
        return new ConcreteProductB3("工場B - 製品3");
    }
}

5-1. Client.java

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Client {
    public static void main(String[] args) {
        List<AbstractFactory> factorys = new ArrayList<AbstractFactory>();
        factorys.add(AbstractFactory.createFactory(ConcreteFactoryA.id));
        factorys.add(AbstractFactory.createFactory(ConcreteFactoryB.id));
        Iterator<AbstractFactory> it = factorys.iterator();
        while (it.hasNext()){
            AbstractFactory factory = it.next();
            AbstractProduct1 product1 = factory.createProduct1();
            AbstractProduct2 product2 = factory.createProduct2();
            AbstractProduct3 product3 = factory.createProduct3();
            product1.execute();
            product2.run();
            product3.action();
        }
    }
}

実行結果

C:\sample\desin_pattern\abstract_factory>javac Client.java [Enter]

C:\sample\desin_pattern\abstract_factory>java Client [Enter]
工場A - 製品1 完成(A1-execute)!
工場A - 製品2 完成(A2-run)!
工場A - 製品3 完成(A3-action)!
工場B - 製品1 完成(B1-execute)!
工場B - 製品2 完成(B2-run)!
工場B - 製品3 完成(B3-action)!
        

▲PageTop