Help us understand the problem. What is going on with this article?

デザインパターン ~Factory Method~

1. はじめに

GoFのデザインパターンにおける、Factory Methodパターンについてまとめます。

2. Factory Methodパターンとは

  • Factoryという英単語は、工場という意味になります。
  • Factory Methodパターンは、インスタンスの作り方をスーパークラスで定め、具体的な生成処理はサブクラス側で行う方式です。
  • インスタンスを生成する工場をTmplate Methodパターンで構成したものがFactory Methodパターンになります。
  • GoFのデザインパターンでは、生成に関するデザインパターンに分類されます。

3. サンプルクラス図

FactoryMethod.PNG

4. サンプルプログラム

IDカード工場から、IDカードを作成するプログラムです。

4-1. Factoryクラス

Factoryの基底となるクラスです。インスタンスの作り方を定めます。

Factory.java
package framework;

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);
}

4-2. Productクラス

Factoryにて生成されるオブジェクトの基底となるクラスです。

Product.java
package framework;

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

4-3. IDCardFactoryクラス

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

IDCardFactory.java
package idcard;
import java.util.ArrayList;

import framework.Factory;
import framework.Product;

public class IDCardFactory extends Factory {

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

    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;
    }
}

4-4. IDCardクラス

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

IDCard.java
package idcard;
import framework.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-5. Mainクラス

メイン処理を行うクラスです。

Main.java
import framework.*;
import idcard.*;

public class Main {
    public static void main(String[] args) {
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("山田");
        Product card2 = factory.create("鈴木");
        Product card3 = factory.create("佐藤");
        card1.use();
        card2.use();
        card3.use();
    }
}

4-6. 実行結果

山田のカードを作ります。
鈴木のカードを作ります。
佐藤のカードを作ります。
山田のカードを使います。
鈴木のカードを使います。
佐藤のカードを使います。

5. メリット

Factory/Productはframeworkパッケージ、IDCardFactory/IDCardはidcardパッケージに存在します。
frameworkパッケージでは、idcardパッケージをインポートしていません。つまり、frameworkパッケージでは、idcardパッケージに依存しない形になっています。
全く別の「製品」と「工場」を作ろうとした場合、frameworkパッケージの中身を修正する必要がなくなります。

6. GitHub

7. デザインパターン一覧

8. 参考

今回の記事、及びサンプルプログラムは、以下の書籍を元に作成させて頂きました。

大変分かりやすく、勉強になりました。感謝申し上げます。
デザインパターンやサンプルプログラムについての説明が詳細に書かれていますので、是非書籍の方もご覧ください。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away