2012年11月27日火曜日

FactoryMethodパターン(ファクトリメソッド・パターン)

FactoryMethodパターンは生成に関するパターンのひとつです。

別名を「Virtual Constructor」と言い
インスタンスの生成をサブクラスに行わせることで
具体的な型を知ることなしに、インスタンスを選択、生成します。

「Template Method パターン」をインスタンス生成に適用させたパターンです。
なので、無意識に使われてるパターンのひとつだと思われます。

Factory Method パターン
Factory Method パターン



インスタンス生成の枠組み(フレームワーク)
 Creator(作成者)・・・・ファクトリの抽象クラス。create対象となる具体的なクラス名を持たない。
               Product(製品)インスタンスを返却するcreateメソッドを持つ。
               createメソッド中ではFactoryMethodを使ってProduct(製品)の生成を行う。
 Product(製品)・・・・・・プロダクトの抽象クラス。具体的なクラス名(製品)を持たない。

肉付け
 ConcreteCreator(具体的な作成者)・・・create対象となる具体的なクラス名持つ。
                         ファクトリメソッドで具体的なインスタンスを生成。
 ConcreteProuct(具体的な製品)・・・・・具体的な製品。


スーパークラス側でフレームワークを作り,サブクラス側で具体的な処理の実装する所が
「Template Method パターン」と同じですね。

----------------------------------------------------
Creatorにあたるクラス
作成者共通の機能を持つ。

ファイル名:Factory.java

package framework;
public abstract class Factory {

   /*
     final修飾子によりこのメソッドは継承させない
     このサンプルでは、createメソッドの処理は拡張できない作り。
    */
    public final Product create(String owner) {
 
        // ファクトリメソッドを使って、インスタンスの生成と、操作を行う。
        Product p = createProduct(owner);
        registerProduct(p);

        // インスタンスを返却
        return p; // Product型なのがポイント(具体的な製品クラスの親)
    }

    // ファクトリーメソッド
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}
----------------------------------------------------
Productクラスにあたるクラス。
製品共通の機能を持つ。

ファイル名:Product.java
package framework;
public abstract class Product {
    public abstract void use();
}
----------------------------------------------------
ConcreteCreatorにあたるクラス。
作成者の具体的な機能を追加し拡張したクラス。

ファイル名:IDCardFactory .java

package idcard;
import framework.*;
import java.util.*;

public class IDCardFactory extends Factory {
    private List owners = new ArrayList();

    // ファクトリメソッドをオーバライド
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }
    protected void registerProduct(Product product) {
        owners.add(((IDCard)product).getOwner());
    }

    // このクラス固有の機能を追加
    public List getOwners() {
        return owners;
    }
}
---------------------------------------------------
ConcreteProductにあたるクラス。
製品の具体的な機能を追加し拡張したクラス。

ファイル名:IDCard.java

package idcard;
import framework.*;
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;
    }
}
-------------------------------------------------
メイン処理

ファイル名: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();
    }
}

0 件のコメント:

コメントを投稿









ロリポップ!なら月々105円から

WordPress、MovableTypeなどの簡単インストール、

アクセス解析、ウェブメーラーが標準装備!






プロペシア