[設計模式]工廠模式——靜態工廠方法(實際不是一種設計模式)


簡介

根據《head first 設計模式》所述,工廠模式共有三種:簡單/靜態工廠、工廠方法抽象工廠

注:其實靜態工廠不是一個設計模式,它更像是一種編程習慣。但是這里是根據[1]所做的筆記,為了方便管理區分,假稱它是工廠模式的一種。

 本文介紹靜態工廠方法。

1、定義:利用靜態方法定義一個簡單的工廠,是靜態工廠。

2、原因:使用靜態工廠模式,是因為不需要使用創建對象的方法來實例化對象,因此可以使用靜態方法來創建一個簡單的工廠。

3、缺點:

· 不能通過繼承來改變創建對象的行為。

· 類如果不含有公有的或者受保護的構造方法,就不能被繼承。

4、優點:

·通常來說,想要獲取實例最常用的方法是被調用類提供一個公有的構造方法,但是使用靜態工廠方法會有更好地彈性,當實現方法改變的時候,只需要更改靜態工廠方法就可以了。

· 和構造方法不一樣,靜態工廠方法可以有自己明確的名字。

· 不必每次調用時都創建一個新對象。使用靜態工廠方法對外提供單例,就是事先准備好一個實例,然后多次調用即可,這樣可以減少重復創建實例,不好的地方是需要注意線程安全問題。

· 可以返回原返回類型的任何子類的對象。

 

5、具體實現(完整代碼): 

  • 靜態工廠:處理創建對象的細節 
public class SimplePizzaFactory{
    public Pizza createPizza(String type){
        Pizza pizza = null;
        if(type.equals("cheese")){
            return new CheesePizza();
        }else if(type.equals("pepperoni")){
            return new PepperoniPizza();
        }else if(type.equals("clam")){
            return new ClamPizza();
        }else if(type.equals("veggie")){
            return new VeggiePizza();
        }else return null;
    }
}
  • 客戶端:用來使用靜態工廠來創建對象 
public class PizzaStore{
    SimplePizzaFactory factory;
    public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;
    }
    public Pizza orderPizza(String type){
        Pizza pizza;
        pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}
  • 抽象產品類: 

 

public abstract class Pizza {
    String name;//名稱
    String dough;//面團類型
    String sauce;//醬料類型
    ArrayList<String> toppings = new ArrayList<String>();//一套佐料
    void prepare(){
        System.out.println("Preparing " + name);
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce... ");
        System.out.println("Adding toppings: ");
        for(int i = 0; i < toppings.size(); i++){
            System.out.println("   " + toppings.get(i));
        }
    }
    void bake(){
        System.out.println("Bake for 25 minutes at 350");
    }
    void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }
    void box(){
        System.out.println("Place pizza in official PizzaStore box");
    }
    public String getName(){
        return name;
    }
    public String toString(){
        StringBuffer display = new StringBuffer();
        display.append("------" + name + "-----\n");
        display.append(dough + "\n");
        display.append(sauce + "\n");
        for(String topping : toppings){
            display.append(topping + "\n");
        }
        return display.toString();
    }
}
  • 具體產品類: 

 

//芝士披薩
public class CheesePizza extends Pizza{
    public CheesePizza(){
        name = "Cheese Pizza";
        dough = "Cheese Dough";
        sauce = "CheeseSauce";

        toppings.add("Cheese Cheese");
    }
}

//蛤蜊披薩
public class ClamPizza extends Pizza{
    public ClamPizza(){
        name = "Clam Pizza";
        dough = "Clam Dough";
        sauce = "Clam Sauce";

        toppings.add("Clam");
    }
}

//意式臘腸披薩
public class PepperoniPizza extends Pizza{
    public PepperoniPizza(){
        name = "Pepperoni Pizza";
        dough = "Pepperoni Dough";
        sauce = "Pepperoni Sauce";

        toppings.add("Pepperoni");
    }
}

//素食披薩
public class VeggiePizza extends Pizza{
    public VeggiePizza(){
        name = "Veggie Pizza";
        dough = "Veggie Dough";
        sauce = "Veggie Sauce";

        toppings.add("Veggie");
    }
}
  • 測試: 
public class PizzaTest{
    public static void main(String[] args){
        SimplePizzaFactory factory = new SimplePizzaFactory();
        PizzaStore store = new PizzaStore(factory);
        Pizza pizza = store.orderPizza("cheese");
        System.out.println("Ethan ordered a " + pizza.getName() + "\n");
        System.out.println(pizza);
        pizza = store.orderPizza("veggie");
        System.out.println("Joel ordered a " + pizza.getName() + '\n');
        System.out.println(pizza);
    }
}

運行結果如下圖所示:

 

參考資料:

[1] head first 設計模式

[2] https://www.jianshu.com/p/fa15f63d399a


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM