Design Pattern | Factory Method(ファクトリメソッド)

Factory Methodパターンとは?

  • Factoryという英単語は工場という意味である。工場では物を仕様に合わせて生産し、要求事項が少し変わればそれに合わせて少し違う物も生産する。
  • 望む仕様を入力すると、それに合うinstanceを生成してくれるのがファクトリメソッドパターンである。
  • Factory Methodパターンは、インスタンスの作り方をスーパークラスで定め、具体的な生成処理はサブクラス側で行う方式である。
  • インスタンスを生成する工場をTemplate Methodパターンで構成したものがFactory Methodパターンである。
  • GoFデザインパターンでは、生成に関するデザインパターンに分類される。

Factory Methodパターンのサンプルプログラム

IDカード工場でIDカードを作るプログラムである。

Class Diagram
Factory Method Pattern Class Diagram

1. Productクラス

Factoryで生成されるオブジェクトの基本となるクラスである。

Product.java

package com.devkuma.designpattern.creational.factorymethod.framwork;

public abstract class Product {
    public abstract void use();
}

2. Factoryクラス

Factoryの基本となるクラスである。インスタンスを生成する。

Factory.java

package com.devkuma.designpattern.creational.factorymethod.framwork;

public abstract class Factory {

    public final Product create(String owner) {
        Product product = createProduct(owner);
        registerProduct(product);
        return product;
    }

    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}

3. IDCardクラス

Productクラスで定義されたメソッドを実装する具象クラスである。

IDCard.java

package com.devkuma.designpattern.creational.factorymethod.idcard;

import com.devkuma.designpattern.creational.factorymethod.framwork.Product;

public class IdCard extends Product {

    private String owner;

    IdCard(String owner) {
        System.out.println(owner + "의 카드를 만듭니다.");
        this.owner = owner;
    }

    public void use() {
        System.out.println(owner + "의 카드를 사용합니다.");
    }

    public String getOwner() {
        return owner;
    }
}

4. IDCardFactoryクラス

Factoryクラスで定義されたメソッドを実装する具象クラスである。

IDCardFactory.java

package com.devkuma.designpattern.creational.factorymethod.idcard;

import com.devkuma.designpattern.creational.factorymethod.framwork.Factory;
import com.devkuma.designpattern.creational.factorymethod.framwork.Product;

import java.util.ArrayList;

public class IdCardFactory extends Factory {

    private ArrayList<String> owners = new ArrayList();

    protected Product createProduct(String owner) {
        return new IdCard(owner);
    }

    protected void registerProduct(Product product) {
        IdCard icCard = (IdCard) product;
        String owner = icCard.getOwner();
        owners.add(owner);
    }

    public ArrayList<String> getOwners() {
        return owners;
    }
}

5. Mainクラス

メイン処理を実行するクラスである。

Main.java

package com.devkuma.designpattern.creational.factorymethod;

import com.devkuma.designpattern.creational.factorymethod.framwork.Factory;
import com.devkuma.designpattern.creational.factorymethod.framwork.Product;
import com.devkuma.designpattern.creational.factorymethod.idcard.IdCardFactory;

public class Main {
    public static void main(String[] args) {
        Factory factory = new IdCardFactory();
        Product card1 = factory.create("devkuma");
        Product card2 = factory.create("kimkc");
        Product card3 = factory.create("yunho");
        card1.use();
        card2.use();
        card3.use();
    }
}

6. 実行結果

devkuma의 카드를 만듭니다.
kimkc의 카드를 만듭니다.
yunho의 카드를 만듭니다.
devkuma의 카드를 사용합니다.
kimkc의 카드를 사용합니다.
yunho의 카드를 사용합니다.

Factory Methodパターンのメリット

Factory/Productはframeworkパッケージ、IDCardFactory/IDCardはidcardパッケージに存在する。
frameworkパッケージはidcardパッケージをimportしない。つまり、frameworkパッケージはidcardパッケージに依存しない形である。
まったく別の「製品」と「工場」を作りたい場合、frameworkパッケージの内容を修正する必要はない。