1. 程式人生 > >工廠模式(head first中簡單工廠和工廠模式的迷惑)

工廠模式(head first中簡單工廠和工廠模式的迷惑)

所有工廠模式都是為了封裝物件的建立

1. 簡單工廠


《head First設計模式》中簡單工廠理解有錯誤。

    又稱靜態工廠模式。主要有靜態工廠方法,抽象產品,具體產品三個角色。

public class SimplePizzaFactory {

    public static Pizza createPizza(String type) {
      if (type.equals("cheese")) {
        return new NYCheesePizza();
      } else if (type.equals("clam")) {
        return new NYClamPizza();
      } else {
        return null;
      }
    }
  }
   <pre name="code" class="java">public class PizzaStore {
    public Pizza orderPizza(String type) {
      Pizza pizza = null;
      pizza = SimplePizzaStory.createPizza(type);
      pizza.prepare();
      pizza.bake();
      pizza.cut();
      pizza.box();
      return Pizza;
    }
  }

如果要增加工廠種類,則需要改動簡單工廠。違反了開閉原則。

2. 工廠方法

工廠方法模式將簡單工廠中的工廠方法則不再是靜態方法。head first中的工廠方法模式即

public class NYPizzaStore {

    public Pizza createPizza(String type) {
      if (type.equals("cheese")) {
        return new NYCheesePizza();
      } else if (type.equals("clam")) {
        return new NYClamPizza();
      } else {
        return null;
      }
    }
  }
   <pre name="code" class="java">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;
    }
    protected abstract Pizza cretePizza(String type);
  }
如果需要增加工廠,只需要重新繼承抽象PizzaStore類。

工廠方法模式適合將客戶程式碼從需要例項化的具體類中解耦。當不知要將來還需要例項化哪些具體類時,也可以考慮使用工廠方法模式。

工廠方法模式定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到子類。基類中的其他類可以自由使用這一方法而不用考慮它到底返回的是怎樣的物件。如何返回要根據子類的實現。

《Head First 設計模式》中的簡單工廠,將工廠方法靜態去掉,本質上已經成了工廠方法模式了。而所謂的具有彈性的框架,只不過是工廠方法模式的兩種實現方式罷了。例如新增一個新的Chicago PizzaStore,按照它的簡單工廠也只需新繼承一個ChicagoPizzaFactory,工廠方法模式則是新新增一個ChicagoPizzaStore。其中簡單工廠並沒有破壞DIP原則。

3. 抽象工廠模式

 抽象工廠模式提供了一個介面,用於建立相關或以來的家族。

抽象工廠利用組合將相關產品(不同類為一組)集合起來。而工廠方法模式則是利用繼承將客戶從實際具體產品中解耦。

public Interface PizzaIngredientFactory {
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
  }
其中每一個createXX方法都可以看作是一個工廠方法。