工厂方法模式的目的是:
通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。
实现
我们还是继续简单工厂模式(Simple Factory Pattern)中的披萨店。
首先我们需要修改一下 Pizza
类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
public abstract class Pizza { public string name; public string dough; public string sauce; public ArrayList toppings = new ArrayList();
public virtual void Prepare() { Console.WriteLine("Prepring " + name); Console.WriteLine("Tossing dough..."); Console.WriteLine("Adding sauce..."); Console.WriteLine("Adding toppings: "); for (int i = 0; i < toppings.Count; i++) Console.WriteLine(" " + toppings[i]); }
public virtual void Bake() { Console.WriteLine("Bake for 25 minutes at 350"); }
public virtual void Cut() { Console.WriteLine("Cutting the pizza into diagonal slices"); }
public virtual void Box() { Console.WriteLine("Place pizza in official PizzaStore box"); }
public String getName() { return name; } }
|
然后通过继承,我们有了几种不同风格和口味的 Pizza
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
public class NYStyleCheesePizza : Pizza { public NYStyleCheesePizza() { name = "NY Style Sauce and Cheese Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce";
toppings.Add("Grated Reggiano Cheese"); } }
public class NYStyleVeggiePizza : Pizza { public NYStyleVeggiePizza() { name = "NY Style Sauce and Veggie Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce";
toppings.Add("Grated Reggiano Veggie"); } }
public class ChicagoStyleCheesePizza : Pizza { public ChicagoStyleCheesePizza() { name = "Chicago Style Deep Dish Cheese Pizza"; dough = "Extra Thick Crust Dough"; sauce = "Plum Tomato Sauce";
toppings.Add("Shredded Mozzarella Cheese"); }
public override void Cut() { Console.WriteLine("Cutting the pizza into square slices"); } }
public class ChicagoStyleVeggiePizza : Pizza { public ChicagoStyleVeggiePizza() { name = "Chicago Style Deep Dish Veggie Pizza"; dough = "Extra Thick Crust Dough"; sauce = "Plum Tomato Sauce";
toppings.Add("Shredded Mozzarella Veggie"); }
public override void Cut() { Console.WriteLine("Cutting the pizza into square slices"); } }
|
相比较之前的写法,新的写法将 Pizza
抽象类中的方法改成了虚方法(virtual
)。这样的话,之后继承此抽象类的子类就不需要某些不用改动的方法进行重复的 override
了。就像代码所展示的一样,我们只对 Cut
方法进行了覆写,因为 Chicago Style 的披萨需要切成方形的。
之后是 PizzaStore
的部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public abstract class PizzaStore { protected abstract Pizza CreatePizza(string type);
public Pizza OrderPizza(string type) { Pizza pizza;
pizza = CreatePizza(type);
pizza.Prepare(); pizza.Bake(); pizza.Cut(); pizza.Box();
return pizza; } }
|
我们将 PizzaStore
也写成了一个抽象类,我们把它称作抽象创造者类,同时还有一个 CreatePizza
的抽象方法。而这就是工厂方法,当然,是抽象的。它返回一个 Pizza
,这就是产品。
继承:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class NYStylePizzaStore : PizzaStore { protected override Pizza CreatePizza(string type) { if (type.Equals("cheese")) return new NYStyleCheesePizza(); else if (type.Equals("viggie")) return new NYStyleVeggiePizza(); else return null; } }
public class ChicagoStylePizzaStore : PizzaStore { protected override Pizza CreatePizza(string type) { if (type.Equals("cheese")) return new ChicagoStyleCheesePizza(); else if (type.Equals("viggie")) return new ChicagoStyleVeggiePizza(); else return null; } }
|
这两个 PizzaStore
的子类(具体创造者)实现了 CreatePizza
抽象方法,这就是真正实现实例化的工厂方法。
我们把实例化的工作都交给了子类,或者说是交给了子类中的一个方法,这个方法就是一个工厂。
注意的点
- 简单工厂和工厂方法之间的差异:简单方法把全部的事情都在一个地方做完了,而工厂方法则是定义了一个框架,通过继承抽象类来创造实际的产品。
代码
FactoryMethodPattern