Dyuichi Blog

オブジェクト指向シリーズⅣ: デザインパターン [⑧ Abstract Factory]

概要

abstract factoryは日本語で「抽象的な工場」という意味になる.Abstrat Factoryパターンは,関連するオブジェクト群を生成するためのインターフェースを提供するパターンである.

Abstract Factoryパターンの主な要素は以下である.

  • AbstractFactory:オブジェクト要素にアクセスし,走査するためのインターフェースを定義する
  • ConcreteFactory:Iteratorインターフェースを実装する.
  • AbstractProduct:Iteratorオブジェクトを生成するインターフェースを定義する
  • ConcreteProduct:Aggregateインターフェースを実装し,ConcreteIteratorのインスタンスを返す.

クラス図

画像が読み込まれない場合はページを更新してみてください。

実装例(Java)

ProductAとProductBはFactoryX,FactoryYに共通している.例えば,以下のような対応関係をもって考えるとわかりやすいかもしれない.

  • ProductA ⇒ キーボード
  • ProductB ⇒ ディスプレイ
  • FactoryX ⇒ Windows
  • FactoryY ⇒ Mac
java// Abstract Product
interface ProductA {
    void operationA();
}

interface ProductB {
    void operationB();
}

// Concrete Product
class ConcreteProductAX implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductAX operationA");
    }
}

class ConcreteProductAY implements ProductA {
    @Override
    public void operationA() {
        System.out.println("ConcreteProductAY operationA");
    }
}

class ConcreteProductBX implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductBX operationB");
    }
}

class ConcreteProductBY implements ProductB {
    @Override
    public void operationB() {
        System.out.println("ConcreteProductBY operationB");
    }
}

// Abstract Factory
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// Concrete Factory
class ConcreteFactoryX implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductAX();
    }
    @Override
    public ProductB createProductB() {
        return new ConcreteProductBX();
    }
}

class ConcreteFactoryY implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductAY();
    }
    @Override
    public ProductB createProductB() {
        return new ConcreteProductBY();
    }
}

// Client
public class AbstractFactoryPattern {
    public static void main(String[] args) {
        AbstractFactory factory;

        // Using X factory
        factory = new ConcreteFactoryX();
        factory.createProductA().operationA();
        factory.createProductB().operationB();

        System.out.println();

        // Using Y factory
        factory = new ConcreteFactoryY();
        factory.createProductA().operationA();
        factory.createProductB().operationB();
    }
}

まとめ,所感

Abstract Factoryパターンを用いることで,中身の構成は同じだが,より具体的には一つ一つの部品が異なる場合にも,同じメソッドで各部品にアクセスできる.

つまり,一つ一つの部品クラスを隠蔽できるということである.

例えば,MacBookファクトリのMac用キーボードインスタンスを取得するのと同じように,WindowsファクトリのWindows用キーボードインスタンスを取得できる.

ファクトリ内のオブジェクトの入れ替えもしやすいと言える.