Factory Method

factory-method.png

ポイント

simple-factoryみたいにFactory用のクラスを作るのではなく、
abstractクラスを作って、その中にabstractなFactory関数を用意する、というやり方である。

利点

  • サブクラスを作ることができる。

実装の仕方

public abstract class PizzaStore {
    public  Pizza orderPizza(String type){
        Pizza pizza = null;
        pizza=createPizza(type);//工場
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    //抽象でファクトリな関数 サブクラスで好きに実装してね★
    abstract Pizza createPizza(String type);
}
サブクラス1Shakeys.java サブクラス2Cappricciosas.java
public class Shakeys extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        Pizza pizza=null;
        if(type.equals("チーズ")){
            pizza=new USACheesePizza();
        }else if(type.equals("生ハム")){
            pizza=new USARawHam();
        }else if(type.equals("マルゲリータ")){
            pizza=new USAMargherita();
        }
        return pizza;
    }
}
public class Capricciosas extends PizzaStore  {
    @Override
    Pizza createPizza(String type) {
        Pizza pizza=null;
        if(type.equals("チーズ")){
            pizza=new ItalianCheesePizza();
        }else if(type.equals("生ハム")){
            pizza=new ItalianRawHam();
        }else if(type.equals("マルゲリータ")){
            pizza=new ItalianMargherita();
        }
        return pizza;
    }
 
}

シェーキーズではアメリカ風のピザを返し、
カプリチョーザではイタリア風のピザを返します。

実際にピザはどんな風に派生させる?

ピザのベースクラス

import java.util.ArrayList;
public abstract class Pizza {
    String name;
    String dough;
    String sauce;
    ArrayList<String> toppings = new ArrayList<String>();
    public void prepare() {
        System.out.println(name+"を下処理"+name);
        System.out.println("生地をこねる");
        System.out.println("ソースを追加");
        System.out.println("トッピングを追加");
        for(String t:toppings){
            System.out.println(" "+t);
        }    
    }
    public void bake() {
        System.out.println("350ドで25分間焼く");
    }
    public void cut() {
        System.out.println("ピザを扇形に切り分ける");    
    }
    public void box() {
        System.out.println("PIzzaStor()の正式な箱にピザを入れる");    
    }
    public String getName(){
        return name;
    }
}
サブクラス1USACheesePizza .java サブクラス2ItalianCheesePizza .java
public class USACheesePizza extends Pizza {
    public USACheesePizza(){
        name="普通のチーズ";
        dough="薄い生地";
        sauce="トマトソース";
        toppings.add("粉レッジャーノチーズ");
    }
 
}
public class ItalianCheesePizza extends Pizza {
    public ItalianCheesePizza(){
        name="おいしいチーズ";
        dough="モチモチの生地";
        sauce="クリームソース";
        toppings.add("パルミジャーノ・レッジャーノチーズ");
    }
}

いざ、使う時

class Main {
    public static void main(String[] args) {
        PizzaStore shakeys=new Shakeys();
        PizzaStore capricciosas=new Capricciosas();
        Pizza pizza=shakeys.orderPizza("チーズ");
        System.out.println("ミッフィーは"+pizza.getName()+"を注文");
        pizza=capricciosas.orderPizza("チーズ");
        System.out.println("ソラちゃんは"+pizza.getName()+"を注文");
    }
 
}

宣言はベースクラスでするけど、定義はサブクラスにすることがポイント。

出力結果

普通のチーズを下処理普通のチーズ
生地をこねる
ソースを追加
トッピングを追加
 粉レッジャーノチーズ
350ドで25分間焼く
ピザを扇形に切り分ける
PIzzaStor()の正式な箱にピザを入れる
ミッフィーは普通のチーズを注文
おいしいチーズを下処理おいしいチーズ
生地をこねる
ソースを追加
トッピングを追加
 パルミジャーノ・レッジャーノチーズ
350ドで25分間焼く
ピザを扇形に切り分ける
PIzzaStor()の正式な箱にピザを入れる
ソラちゃんはおいしいチーズを注文

hollywood-principle

サポートサイト Wikidot.com hollywood-principle