一、
1."工厂模式"不是种真正的设计模式,而是一种编程术语
2.The Factory Method Pattern defi nes an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
3.The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
二、简单工厂
1.根据情况,new 出来的对象是不同类型的子类,所以会变化是初始化部分,所以根据OO原则,把初始化操作抽取出来封装
2.把产生的不同类型对象的if elseif else new xxx(),抽离出来有什么好处?答:(1)可以为不同的客户端提供相同的初始化机制(2)
3.
4.
1 package headfirst.designpatterns.factory.pizzas; 2 3 import java.util.ArrayList; 4 5 abstract public class Pizza { 6 String name; 7 String dough; 8 String sauce; 9 ArrayList<String> toppings = new ArrayList<String>(); 10 11 public String getName() { 12 return name; 13 } 14 15 public void prepare() { 16 System.out.println("Preparing " + name); 17 } 18 19 public void bake() { 20 System.out.println("Baking " + name); 21 } 22 23 public void cut() { 24 System.out.println("Cutting " + name); 25 } 26 27 public void box() { 28 System.out.println("Boxing " + name); 29 } 30 31 public String toString() { 32 // code to display pizza name and ingredients 33 StringBuffer display = new StringBuffer(); 34 display.append("---- " + name + " ---- "); 35 display.append(dough + " "); 36 display.append(sauce + " "); 37 for (String topping : toppings) { 38 display.append(topping + " "); 39 } 40 return display.toString(); 41 } 42 }
5.
1 package headfirst.designpatterns.factory.pizzas; 2 3 public class CheesePizza extends Pizza { 4 public CheesePizza() { 5 name = "Cheese Pizza"; 6 dough = "Regular Crust"; 7 sauce = "Marinara Pizza Sauce"; 8 toppings.add("Fresh Mozzarella"); 9 toppings.add("Parmesan"); 10 } 11 }
6.
1 package headfirst.designpatterns.factory.pizzas; 2 3 public class PizzaStore { 4 SimplePizzaFactory factory; 5 6 public PizzaStore(SimplePizzaFactory factory) { 7 this.factory = factory; 8 } 9 10 public Pizza orderPizza(String type) { 11 Pizza pizza; 12 13 pizza = factory.createPizza(type); 14 15 pizza.prepare(); 16 pizza.bake(); 17 pizza.cut(); 18 pizza.box(); 19 20 return pizza; 21 } 22 23 }
7.
1 package headfirst.designpatterns.factory.pizzas; 2 3 public class SimplePizzaFactory { 4 5 public Pizza createPizza(String type) { 6 Pizza pizza = null; 7 8 if (type.equals("cheese")) { 9 pizza = new CheesePizza(); 10 } else if (type.equals("pepperoni")) { 11 pizza = new PepperoniPizza(); 12 } else if (type.equals("clam")) { 13 pizza = new ClamPizza(); 14 } else if (type.equals("veggie")) { 15 pizza = new VeggiePizza(); 16 } 17 return pizza; 18 } 19 }
三、工厂方法模式
1.上面简单工厂的创建pizza是绑定在createPizza()里的,不灵活,可以把createPizza()改为抽象方法,由不同如ChicagoPizzaStore、NYPizzaStore去实现,则可以解耦,实现运行时绑定
The following guidelines can help you avoid OO designs that violate the Dependency Inversion Principle:
No variable should hold a reference to a concrete class.
No class should derive from a concrete class.
No method should override an implemented method of any of its base classes.--》If you override an implemented method,then your base class wasn’t really an abstraction to start with. Those methods implemented in the base class are
meant to be shared by all your subclasses.
2.
3.
4.
5.抽象工厂其实就是在两个维度上抽象(1)在产品上(2)在creator上,注意在creator中有抽象了一个factoryMehtod(),如下图
6.
1 package headfirst.designpatterns.factory.pizzafm; 2 3 public abstract class PizzaStore { 4 5 abstract Pizza createPizza(String item); 6 7 public Pizza orderPizza(String type) { 8 Pizza pizza = createPizza(type); 9 System.out.println("--- Making a " + pizza.getName() + " ---"); 10 pizza.prepare(); 11 pizza.bake(); 12 pizza.cut(); 13 pizza.box(); 14 return pizza; 15 } 16 }
7.
1 package headfirst.designpatterns.factory.pizzafm; 2 3 public class ChicagoPizzaStore extends PizzaStore { 4 5 Pizza createPizza(String item) { 6 if (item.equals("cheese")) { 7 return new ChicagoStyleCheesePizza(); 8 } else if (item.equals("veggie")) { 9 return new ChicagoStyleVeggiePizza(); 10 } else if (item.equals("clam")) { 11 return new ChicagoStyleClamPizza(); 12 } else if (item.equals("pepperoni")) { 13 return new ChicagoStylePepperoniPizza(); 14 } else return null; 15 } 16 }
8.
1 package headfirst.designpatterns.factory.pizzafm; 2 3 public class NYPizzaStore extends PizzaStore { 4 5 Pizza createPizza(String item) { 6 if (item.equals("cheese")) { 7 return new NYStyleCheesePizza(); 8 } else if (item.equals("veggie")) { 9 return new NYStyleVeggiePizza(); 10 } else if (item.equals("clam")) { 11 return new NYStyleClamPizza(); 12 } else if (item.equals("pepperoni")) { 13 return new NYStylePepperoniPizza(); 14 } else return null; 15 } 16 }
9.
1 package headfirst.designpatterns.factory.pizzafm; 2 3 public class ChicagoStyleCheesePizza extends Pizza { 4 5 public ChicagoStyleCheesePizza() { 6 name = "Chicago Style Deep Dish Cheese Pizza"; 7 dough = "Extra Thick Crust Dough"; 8 sauce = "Plum Tomato Sauce"; 9 10 toppings.add("Shredded Mozzarella Cheese"); 11 } 12 13 void cut() { 14 System.out.println("Cutting the pizza into square slices"); 15 } 16 }
10.
1 package headfirst.designpatterns.factory.pizzafm; 2 3 public class NYStyleCheesePizza extends Pizza { 4 5 public NYStyleCheesePizza() { 6 name = "NY Style Sauce and Cheese Pizza"; 7 dough = "Thin Crust Dough"; 8 sauce = "Marinara Sauce"; 9 10 toppings.add("Grated Reggiano Cheese"); 11 } 12 }
四、抽象工厂
1.
2.
3.
package headfirst.designpatterns.factory.pizzaaf; public abstract class PizzaStore { protected abstract Pizza createPizza(String item); public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); System.out.println("--- Making a " + pizza.getName() + " ---"); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
4.
package headfirst.designpatterns.factory.pizzaaf; public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { public Dough createDough() { return new ThickCrustDough(); } public Sauce createSauce() { return new PlumTomatoSauce(); } public Cheese createCheese() { return new MozzarellaCheese(); } public Veggies[] createVeggies() { Veggies veggies[] = { new BlackOlives(), new Spinach(), new Eggplant() }; return veggies; } public Pepperoni createPepperoni() { return new SlicedPepperoni(); } public Clams createClam() { return new FrozenClams(); } }
5.
package headfirst.designpatterns.factory.pizzaaf; public abstract class Pizza { String name; Dough dough; Sauce sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepperoni; Clams clam; abstract void prepare(); 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"); } void setName(String name) { this.name = name; } String getName() { return name; } public String toString() { StringBuffer result = new StringBuffer(); result.append("---- " + name + " ---- "); if (dough != null) { result.append(dough); result.append(" "); } if (sauce != null) { result.append(sauce); result.append(" "); } if (cheese != null) { result.append(cheese); result.append(" "); } if (veggies != null) { for (int i = 0; i < veggies.length; i++) { result.append(veggies[i]); if (i < veggies.length-1) { result.append(", "); } } result.append(" "); } if (clam != null) { result.append(clam); result.append(" "); } if (pepperoni != null) { result.append(pepperoni); result.append(" "); } return result.toString(); } }
6.
1 package headfirst.designpatterns.factory.pizzaaf; 2 3 public interface Dough { 4 public String toString(); 5 }
7.
1 package headfirst.designpatterns.factory.pizzaaf; 2 3 public class ThickCrustDough implements Dough { 4 public String toString() { 5 return "ThickCrust style extra thick crust dough"; 6 } 7 }
8.
1 package headfirst.designpatterns.factory.pizzaaf; 2 3 public class PizzaTestDrive { 4 5 public static void main(String[] args) { 6 PizzaStore nyStore = new NYPizzaStore(); 7 PizzaStore chicagoStore = new ChicagoPizzaStore(); 8 9 Pizza pizza = nyStore.orderPizza("cheese"); 10 System.out.println("Ethan ordered a " + pizza + " "); 11 12 pizza = chicagoStore.orderPizza("cheese"); 13 System.out.println("Joel ordered a " + pizza + " "); 14 15 pizza = nyStore.orderPizza("clam"); 16 System.out.println("Ethan ordered a " + pizza + " "); 17 18 pizza = chicagoStore.orderPizza("clam"); 19 System.out.println("Joel ordered a " + pizza + " "); 20 21 pizza = nyStore.orderPizza("pepperoni"); 22 System.out.println("Ethan ordered a " + pizza + " "); 23 24 pizza = chicagoStore.orderPizza("pepperoni"); 25 System.out.println("Joel ordered a " + pizza + " "); 26 27 pizza = nyStore.orderPizza("veggie"); 28 System.out.println("Ethan ordered a " + pizza + " "); 29 30 pizza = chicagoStore.orderPizza("veggie"); 31 System.out.println("Joel ordered a " + pizza + " "); 32 } 33 }
9.
五、工厂方法与抽象工厂的对比
1.
2.
3.