创建型设计模式——工厂方法模式

简介: 创建型设计模式——工厂方法模式

1.什么是工厂方法模式?


1.    工厂方法模式设计方案:  将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。

2.    工厂方法模式:  定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

何时使用?不同条件下创建不用实例时。方法是让子类实现工厂接口。

2.案例实现


假如说,我们现在有这样一个需求:客户在点披萨时,可以点不同口味的披萨,比如北京的奶酪pizza、北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza。披萨的制作有preparebake, cut, box;完成披萨店订购功能。

那么可以画一个简单的类图如下:

具体的代码我们就可以这样写:↓↓↓↓↓↓

首先是一个Pizza类,这里将它声明为抽象类,主要原因是其中的prepare方法不是恒定不变的,而是由实现它的子类来完成。

package com.szh.factory.factorymethod.pizza;
/**
 * 声明Pizza类为抽象类
 */
public abstract class Pizza {
    //Pizza名称
    protected String name;
    //准备原材料,不同的披萨不一样。因此,我们做成抽象方法,具体的原材料实现交给它的子类去完成
    public abstract void prepare();
    //烘烤
    public void bake() {
        System.out.println(name + " baking;");
    }
    //切割
    public void cut() {
        System.out.println(name + " cutting;");
    }
    //打包
    public void box() {
        System.out.println(name + " boxing;");
    }
    public void setName(String name) {
        this.name = name;
    }
}
package com.szh.factory.factorymethod.pizza;
public class BJCheesePizza extends Pizza {
  @Override
  public void prepare() {
    setName("北京的奶酪pizza");
    System.out.println("北京的奶酪pizza 准备原材料");
  }
}
package com.szh.factory.factorymethod.pizza;
public class BJPepperPizza extends Pizza {
  @Override
  public void prepare() {
    setName("北京的胡椒pizza");
    System.out.println("北京的胡椒pizza 准备原材料");
  }
}
package com.szh.factory.factorymethod.pizza;
public class LDCheesePizza extends Pizza{
  @Override
  public void prepare() {
    setName("伦敦的奶酪pizza");
    System.out.println("伦敦的奶酪pizza 准备原材料");
  }
}
package com.szh.factory.factorymethod.pizza;
public class LDPepperPizza extends Pizza{
  @Override
  public void prepare() {
    setName("伦敦的胡椒pizza");
    System.out.println("伦敦的胡椒pizza 准备原材料");
  }
}

下面是订购Pizza的相关代码。说制作披萨的原材料是什么怎么做,我们此时此刻不关心,那么就可以将它延迟到子类中实现。

package com.szh.factory.factorymethod.order;
import com.szh.factory.factorymethod.pizza.Pizza;
import java.util.Scanner;
public abstract class OrderPizza {
    //定义一个抽象方法, createPizza, 让各个工厂子类自己实现
    abstract Pizza createPizza(String orderType);
    public OrderPizza() {
        Pizza pizza = null;
        String orderType = "";
        do {
            orderType = getType();
            pizza = createPizza(orderType); //抽象方法, 由工厂子类完成
            // 输出pizza 制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }
    private String getType() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入 pizza 种类: ");
        String str = scanner.nextLine();
        return str;
    }
}
package com.szh.factorymethod.order;
import com.szh.factorymethod.pizza.BJCheesePizza;
import com.szh.factorymethod.pizza.BJPepperPizza;
import com.szh.factorymethod.pizza.Pizza;
public class BJOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if ("cheese".equals(orderType)) {
            pizza = new BJCheesePizza();
        } else if ("pepper".equals(orderType)) {
            pizza = new BJPepperPizza();
        } else {
            throw new NullPointerException("暂无该Pizza种类....");
        }
        return pizza;
    }
}
package com.szh.factorymethod.order;
import com.szh.factorymethod.pizza.LDCheesePizza;
import com.szh.factorymethod.pizza.LDPepperPizza;
import com.szh.factorymethod.pizza.Pizza;
public class LDOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if ("cheese".equals(orderType)) {
            pizza = new LDCheesePizza();
        } else if ("pepper".equals(orderType)) {
            pizza = new LDPepperPizza();
        } else {
            throw new NullPointerException("暂无该Pizza种类....");
        }
        return pizza;
    }
}

最后我们测试一下。

package com.szh.factorymethod;
import com.szh.factorymethod.order.BJOrderPizza;
import com.szh.factorymethod.order.LDOrderPizza;
import java.util.Scanner;
public class MainTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String content = scanner.next();
        if ("Beijing".equals(content)) {
            new BJOrderPizza();
        } else if ("London".equals(content)) {
            new LDOrderPizza();
        } else {
            System.out.println("无法预先匹配Pizza种类....");
            scanner.close();
        }
    }
}


3.JDK中的工厂方法模式


java.util.Calendar 这个类中就有。

相关文章
|
3天前
|
设计模式 搜索推荐 数据库连接
第二篇 创建型设计模式 - 灵活、解耦的创建机制
第二篇 创建型设计模式 - 灵活、解耦的创建机制
|
4天前
|
设计模式 API
【设计模式】适配器和桥接器模式有什么区别
【设计模式】适配器和桥接器模式有什么区别
8 1
|
4天前
|
设计模式
【设计模式】张一鸣笔记:责任链接模式怎么用?
【设计模式】张一鸣笔记:责任链接模式怎么用?
11 1
|
4天前
|
设计模式 uml
【设计模式】建造者模式就是游戏模式吗?
【设计模式】建造者模式就是游戏模式吗?
11 0
|
4天前
|
设计模式 Java uml
【设计模式】什么是工厂方法模式?
【设计模式】什么是工厂方法模式?
8 1
|
4天前
|
设计模式 uml
【设计模式】一文搞定简单工厂模式!
【设计模式】一文搞定简单工厂模式!
8 2
|
4天前
|
设计模式 JavaScript 前端开发
js设计模式-观察者模式与发布/订阅模式
观察者模式和发布/订阅模式是JavaScript中的两种设计模式,用于处理对象间的通信和事件处理。观察者模式中,一个主题对象状态改变会通知所有观察者。实现包括定义主题和观察者对象,以及在主题中添加、删除和通知观察者的功能。发布/订阅模式则引入事件管理器,允许发布者发布事件,订阅者通过订阅接收通知。
|
4天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
24 4
|
4天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
39 2
|
4天前
|
设计模式 JavaScript 前端开发
[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式
[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式