iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
自我挑戰組

深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享系列 第 14

[深入淺出設計模式] Ch4 The Factory Pattern (4) - 【工廠模式】範例: Pizza Store

  • 分享至 

  • xImage
  •  

工廠模式 範例: Pizza Store

上篇我們已經完成工廠跟Pizza的抽象類別,現在來看看子類別要如何實現Pizza(),在這之前要先完成食材的類別(這邊以Cheese()示範,完整程式碼點文章最後連結):

public interface Cheese{   
    public String getName();
}

public class CheddarCheese implements Cheese{
    protected String name;
    public CheddarCheese(){
        this.name = "CheddarCheese";
    }
    public String getName(){
        return this.name;
    }
}

public class MozzarellaCheese implements Cheese{
    protected String name;
    public MozzarellaCheese(){
        this.name = "MozzarellaCheese";
    }
    public String getName(){
        return this.name;
    }
}
public class CheesePizza extends Pizza{
    IngredientFactory factory;

    public  CheesePizza(IngredientFactory factory){
        this.factory = factory;
    }

    public void prepare(){
        System.out.println("Preparing "+ this.name);

        //用特定工廠的食材
        dough = factory.createDough();
        sauce = factory.createSauce();
        cheese = factory.createCheese();
    }
}

public class SeafoodPizza extends Pizza{
    IngredientFactory factory;

    public  SeafoodPizza(IngredientFactory factory){
        this.factory = factory;
    }

    public void prepare(){
        System.out.println("Preparing "+ this.name);

        //用特定工廠的食材
        dough = factory.createDough();
        sauce = factory.createSauce();
        cheese = factory.createCheese();
        seafood = factory.createSeafood();
    }
}

即使都是CheesePizza(),若是由不同工廠生產的,利用不同子類別去繼承同種食材的介面,就可以有一些地區差異的彈性,,而食材的製造過程由工廠實行。

public class ChicagoPizzaFactory implements IngredientFactory{
    public Dough createDough(){
        Dough dough = new ThickDough();       
        return dough;
    }

    public Sauce createSauce(){
        //醬汁的子類別是茄汁
        Sauce sauce = new Ketchup();
        return sauce;
    }

    public Cheese createCheese(){
        Cheese cheese = new MozzarellaCheese();       
        return cheese;
    }

    public Seafood createSeafood(){
        Seafood clam = new Clam();
        return clam;
    }
    
    public Veggies createVeggies() {
        Veggies onion = new Onion();
        return onion;
    }
}

public class NYPizzaFactory implements IngredientFactory{
    public Dough createDough(){
        Dough dough = new ThinDough();
        return dough;
    }
    public Sauce createSauce(){
        //醬汁的子類別是白醬
        Sauce sauce = new WhiteSauce();
        return sauce;
    }
    public Cheese createCheese(){
        Cheese cheese = new CheddarCheese();
        return cheese;
    }
    public Seafood createSeafood(){
        Seafood shrimp = new FrozenShrimp();
        return shrimp;
    }
    public Veggies createVeggies() {
        Veggies onion = new Pea();
        return onion;
    }
}

最後可以從PizzaStore()子類別去了解整個流程,客人點餐以後,orderPizza()會呼叫createPizza()
由指定的工廠去生產某個口味的Pizza食材,pizza.prepare()把食材組成Pizza,再送回店裡做剩下的 bake() cut() box()

public abstract class PizzaStore {
   abstract protected Pizza createPizza(String item);
   abstract void orderPizza(String item);
}

public class NYPizzaStore extends PizzaStore{
    
    protected Pizza createPizza(String item){
        Pizza pizza = null;
        IngredientFactory NYFactory = new NYPizzaFactory();

        if(item.equals("cheese")){
            pizza = new CheesePizza(NYFactory);
            pizza.setName("NY Cheese Pizza");
        }
        else if(item.equals("vegan")){
            pizza = new VeganPizza(NYFactory);
            pizza.setName("NY Vegan Pizza");
        }
        else if(item.equals("seafood")){
            pizza = new SeafoodPizza(NYFactory);            
            pizza.setName("NY forzen seafood Pizza :))");
        }
        else{
            pizza = new ComboPizza(NYFactory);
            pizza.setName("NY style mix favor combo pizza");
        }
        return pizza;
    }

    public void orderPizza(String item){
        Pizza pizza = createPizza(item);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        pizza.getName();
        System.out.println("Your order is ready! ");
    }
}

public class FactoryPattern {
   
    public static void main(String[] args) {
        PizzaStore nyPizzaStore = new NYPizzaStore();
        nyPizzaStore.orderPizza("seafood");
        System.out.println("_________________________");
        PizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
        chicagoPizzaStore.orderPizza("seafood");
    }
}

輸出結果可以看到不同分店的同樣口味使用子類別的食材不同

https://ithelp.ithome.com.tw/upload/images/20230930/20163178JLlWSfQtCw.png


參考資料:

  1. 《深入淺出設計模式 (Head First Design Patterns) 》
  2. 書中官方程式碼傳送門

本篇完整程式

https://github.com/changtintin/Design-Pattern/tree/master/Ch4/Java/FactoryPattern


Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!


上一篇
[深入淺出設計模式] Ch4 The Factory Pattern (3) - 【工廠模式】範例: Pizza Store
下一篇
[深入淺出設計模式] Ch4 The Factory Pattern (5) - 【抽象工廠模式】Abstract Factory Pattern 與工廠方法模式差在哪裡?
系列文
深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言