工厂模式分类:

  1. 简单工厂:明确地计划不同条件下创建不同实例时;
  2. 优化后的工厂:同上;
  3. 抽象工厂:系统的产品有多个的产品 族,而系统只消费其中某一族的产品。

1.简单工厂:

简单工厂适合的场景:

我们需要一辆汽车,可以直接从工厂里面提货。
我们既不用去管这辆汽车是怎么做出来的,也不用知道这个汽车里面的具体实现。

简单工厂的类图:

SimpleFactoryPattern.png
很明显,SimpleFactories将负责createPizza(String pizzaName),调用者应该使用SimpleFactories
SimpleFactoryPattern2带依赖关系.png
SimpleFactory们和Pizza们之间使用虚线箭头关联,这意味着他们之间的依赖很低。而其中,具体的SimpleFactory(即SimpleFactoryInKaizhou)负责真正的Pizza制造。
本⽂以以上UML实例为例。

具体的SimpleFactory们的代码:

  1. public class SimpleFactoryInKaizhou implements SimpleFactory {
  2. public Pizza createPizza(String pizzaName) {
  3. Pizza pizza = null;
  4. if (pizzaName.equals("cheese")) {
  5. pizza = new CheesePizza();
  6. } else if (pizzaName.equals("greek")) {
  7. pizza = new GreekPizza();
  8. } else if (pizzaName.equals("pepper")) {
  9. pizza = new PepperPizza();
  10. }
  11. pizza.pizzaName = pizzaName;
  12. return pizza;
  13. }
  14. }

2.优化后的工厂模式:

工厂模式类图:

FactoryMethon.png
本⽂以此UML实例为例。

当前工厂模式的解释:

  • 工厂现在贴合语义,变成了PizzaStore
  • 工厂PizzaStore和产品Pizza变成了关联关系
  • 工厂PizzaStore仍然承诺负责_createPizza(String pizzaName)_,但真正创建产品Pizza的任务交给了工厂PizzaStore的具体子类;
  • 工厂PizzaStore提供了orderPizza(String pizzaName);来实现所有工厂都将可以提供点餐服务,具体子类将在此生产具体产品。

    Pizza们:

    抽象的Pizza

    声明作为Pizza的属性及其方法:

    1. public abstract class Pizza {
    2. public String pizzaName; //披萨名字
    3. public String doughName; //面团名字
    4. public String sauceName; //酱料名字
    5. public ArrayList<String> toppingNames = null; //配料名字
    6. public abstract void prepare(); //本实例中,这个方法将充当 构造器 的初始化任务
    7. public abstract void cut();
    8. public abstract void bake();
    9. public abstract void box();
    10. public String toString() {
    11. String ret = "This is a " + pizzaName + " WITH " + doughName + " " + sauceName;
    12. if (toppingNames != null) {
    13. for (String t : toppingNames) {
    14. ret = ret + " " + t;
    15. }
    16. }
    17. return ret;
    18. }
    19. }

    KaizhouCheesePizza

    具体的Pizza产品,是真正被使用的Pizza

    1. public class KaizhouCheesePizza extends Pizza {
    2. public void prepare() { //充当构造器
    3. this.pizzaName = "CheesePizza";
    4. this.doughName = "KaizhouDough";
    5. this.sauceName = "KaizhouSauce";
    6. toppingNames = new ArrayList<>();
    7. toppingNames.add("rice");
    8. toppingNames.add("water");
    9. }
    10. public void cut() {
    11. System.out.println("Cutting KaizhouCheesePizza!");
    12. }
    13. public void bake() {
    14. System.out.println("Baking KaizhouCheesePizza!");
    15. }
    16. public void box() {
    17. System.out.println("Boxing KaizhouCheesePizza!");
    18. }
    19. }

    工厂类PizzaStore们:

    抽象的PizzaStore

    这个类将作为工厂的模板,他承诺能够create pizza,但真正的操作将交给它的具体子类实现:

    1. public abstract class PizzaStore { //Store和Factory合并
    2. public Pizza pizza;
    3. public abstract Pizza createPizza(String pizzaName);//具体的制作由具体的店面实现
    4. public Pizza orderPizza(String pizzaName) {//依然负责所有关于处理pizza的事
    5. pizza = this.createPizza(pizzaName);
    6. pizza.prepare();
    7. pizza.bake();
    8. pizza.cut();
    9. pizza.box();
    10. return pizza;
    11. }
    12. }

    KaizhouPizzaStore
    1. public class KaizhouPizzaStore extends PizzaStore {
    2. public KaizhouPizzaStore() {
    3. System.out.println("\n" + "A KaizhouPizzaStore ready");
    4. }
    5. @Override
    6. public Pizza createPizza(String pizzaName) {
    7. if (pizzaName.equals("cheese")) {
    8. return new KaizhouCheesePizza();
    9. } else if (pizzaName.equals("pepper")) {
    10. return new PepperPizza();
    11. }
    12. return null;
    13. }
    14. }

    工厂模式测试代码:

    1. //合并了Store和Factory
    2. //Store就是工厂,对产品的各种操作在Store里,但是 生产产品 在Store的派生类里面
    3. //使用者只知道各种操作存在,但是具体的操作干了什么,在store派生类中被决定,
    4. public class Main {
    5. public static void main(String s[]) {
    6. Pizza pizza;
    7. PizzaStore pizzaStore;
    8. pizzaStore = new KaizhouPizzaStore(); //指定具体工程
    9. pizza = pizzaStore.orderPizza("cheese");
    10. System.out.println(pizza);
    11. }
    12. }

    优化的工厂模式的要点:

    工厂模式必须提供的能力:
  • 抽象类工厂应该规定子类必须创建对象的方法_protected abstract Pizza createPizza(String pizzaName);_

  • 抽象类工厂应提供对外的获取产品的方法public Pizza orderPizza(String pizzaName);
  • 由上,抽象类工厂应规定orderPizza具有生产Pizza的功能:
    1. public Pizza orderPizza(String pizzaName) {//依然负责所有关于处理pizza的事
    2. pizza = this.createPizza(pizzaName);
    3. //其他code
    4. }
    工厂模式的核心思想:
  1. 工厂定义一个创建对象的接口,
  2. 让其 子类自己 决定实例化哪一个工厂类、产生具体哪一个产品;

工厂模式使其创建过程延迟到 子类 进行。