Factory Pattern
需求: 披萨店提供披萨
原方式:
public class PizzaStore { public Pizza orderPizza() { Pizza pizza = new Pizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
问题:
不利于拓展, 可能有很多相似的类型需要使用这个方法
所以:
令 Pizza 抽象, 不在依赖某一特定类型的 Pizza
public class PizzaStore { public IPizza orderPizza() { IPizza pizza = new APizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
问题:
这样还是无法解决需求变更问问题, 万一需要变成 BPizza, CPizza 呢
所以:
令 orderPizza 做出类似可改变的形式
public class PizzaStore { public IPizza orderPizza(string type) { IPizza pizza = null; switch (type) { case "A": pizza = new APizza(); case "B": pizza = new BPizza(); // and so on } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
问题:
这样依然无法解决需求, 虽然可以通过类型指定不同的 pizza 但是万一今后需求发生扩展, 需要不停的修改 orderPizza 中的方法
这样一来 orderPizza 就担任多个职务, 既要选择产生哪种 pizza 又要制作 pizza 不符合一个方法只做一件事的原则
所以:
简单工厂:
将选择 pizza 的部分抽离 orderPizza 方法 交给工厂类去做, 这样 工厂类可以专心选择制作哪类的 pizza 而 orderPizza 也可以专心制作 pizza 了
public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public IPizza orderPizza(string type) { IPizza pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public class SimplePizzaFactory { public IPizza createPizza(string type) { IPizza pizza = null; switch (type) { case "A": pizza = new APizza(); case "B": pizza = new BPizza(); // and so on } return pizza; } } |
问题: 需要加盟很多的 pizzaStore, 所以可能需要 不同的 craetePizza 实现方法
所以:
工厂模式:
将 PizzaStore 抽象为一个抽象类, 由子类来决定具体化
// 创建者类 public abstract class PizzaStore { abstract IPizza createPizza(string type); public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
// 产品类 public interface IPizza { } |
||
public class APizzaStore : PizzaStore { IPizza createPizza(string type) { IPizza pizza = null; switch (type) { case "1": pizza = new A1Pizza(); case "2": pizza = new A2Pizza(); // and so on } return pizza; } /// <summary> /// 可以重写基类的 orderPizza 也可以不重写 /// </summary> /// <param name="type"></param> /// <returns></returns> public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public class BPizzaStore : PizzaStore { IPizza createPizza(string type) { IPizza pizza = null; switch (type) { case "1": pizza = new B1Pizza(); case "2": pizza = new B2Pizza(); // and so on } return pizza; } /// <summary> /// 可以重写基类的 orderPizza 也可以不重写 /// </summary> /// <param name="type"></param> /// <returns></returns> public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public class A1Pizza : IPizza { // to do something } |
public class A2Pizza : IPizza { // to do something } |
点: 依赖倒置原则, 不能让高层组件依赖低层组件, 而应该都依赖于相同的抽象
扩展:
抽象工厂:
讲工厂从方法里抽象出来, 从实际的工厂中解耦. 利于组合操作
public abstract class PizzaStore { abstract IPizza createPizza(string type); public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public abstract class PizzaFactory { abstract void getPizza(string type); } |
||
public class APizzaStore : PizzaStore { PizzaFactory factory; public APizzaStore(PizzaFactory factory) { this.factory = factory; // new APizzaFactory } IPizza createPizza(string type) { IPizza pizza = factory.getPizza(type); return pizza; } /// <summary> /// 可以重写基类的 orderPizza 也可以不重写 /// </summary> /// <param name="type"></param> /// <returns></returns> public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public class BPizzaStore : PizzaStore { PizzaFactory factory; public BPizzaStore(PizzaFactory factory) { this.factory = factory; // new BPizzaFactory } IPizza createPizza(string type) { IPizza pizza = factory.getPizza(type); return pizza; } /// <summary> /// 可以重写基类的 orderPizza 也可以不重写 /// </summary> /// <param name="type"></param> /// <returns></returns> public IPizza orderPizza(string type) { IPizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } |
public class APizzaFactory : PizzaFactory { void getPizza(string type) { } } |
public class BPizzaFactory : PizzaFactory { void getPizza(string type) { } } |