创建型模式之工厂模式

一、简单工厂模式

1、介绍

简单工厂模式是工厂模式家族中最简单使用的模式,它定义了一个创建对象的类,由这个类来封装实例化对象的行为。在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

2、类图

3、例子

看一个披萨的项目:

  1. 披萨的种类很多(比如:GreekPizza、CheesePizza)
  2. 披萨的制作有 prepare、bake、cut、box
  3. 完成披萨店订购功能

3.1、披萨类

/**
 * 披萨类接口
 */
public abstract class 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;
    }
}
/**
 * 奶酪披萨
 */
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(" 准备材料制作奶酪披萨 ");
    }
}
/**
 * 希腊披萨
 */
public class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(" 准备材料制作希腊披萨 ");
    }
}
/**
 * 胡椒披萨
 */
public class PepperPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(" 准备制作胡椒披萨 ");
    }
}

3.2、实例化类

/**
 * 实例化功能
 */
public class OrderPizza {

    SimpleFactoty simpleFactoty;
    Pizza pizza = null;

    public OrderPizza(SimpleFactoty simpleFactoty){
        setFactory(simpleFactoty);
    }

    public void setFactory(SimpleFactoty simpleFactoty){
        String orderType = "";
        this.simpleFactoty = simpleFactoty;
        do{
            orderType = getType();
            pizza = this.simpleFactoty.createPizza(orderType);
            if(pizza != null){
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
                System.out.println(" 订购失败 ");
                break;
            }
        }while(true);
    }

    // 写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入披萨种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

3.3、简单工厂类

/**
 * 简单工厂类
 */
public class SimpleFactoty {

    public Pizza createPizza(String orderType){

        Pizza pizza = null;

        System.out.println("实用简单工厂模式");
        if(orderType.equals("cheese")){
            pizza = new CheesePizza();
            pizza.setName(" 奶酪披萨 ");
        }else if(orderType.equals("greek")){
            pizza = new GreekPizza();
            pizza.setName(" 希腊披萨 ");
        }else if(orderType.equals("pepper")){
            pizza = new PepperPizza();
            pizza.setName(" 胡椒披萨 ");
        }

        return pizza;
    }
}

3.4、商店类

/**
 * 商店类
 */
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new SimpleFactoty());
    }
}

二、工厂方法模式

1、介绍

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

2、类图

3、例子

披萨项目的新需求:

客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪pizza、北京的胡椒pizza 或者是 伦敦的奶酪pizza、 伦敦的胡椒pizza。

3.1、披萨类

/**
 * 披萨类接口
 */
public abstract class 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;
    }
}
/**
 * 北京奶酪披萨
 */
public class BJCheesePizza extends Pizza {

    @Override
    public void prepare() {
        setName(" 北京的奶酪披萨 ");
        System.out.println(" 准备制作北京奶酪披萨 ");
    }
}
/**
 * 北京胡椒披萨
 */
public class BJPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 北京的胡椒披萨 ");
        System.out.println(" 准备制作北京胡椒披萨 ");
    }
}
/**
 * 伦敦奶酪披萨
 */
public class LDCheesePizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 伦敦的奶酪披萨 ");
        System.out.println(" 准备制作伦敦奶酪披萨 ");
    }
}
/**
 * 伦敦胡椒披萨
 */
public class LDPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 伦敦的胡椒披萨 ");
        System.out.println(" 准备制作伦敦胡椒披萨 ");
    }
}

3.2、实例化类

/**
 * 实例化类接口
 */
public abstract class OrderPizza {
    abstract Pizza createPizza(String orderType);

    public OrderPizza(){
        Pizza pizza = null;
        String orderType = "";
        do{
            orderType = getType();
            pizza=createPizza(orderType);
            if(pizza != null){
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
                System.out.println(" 订购失败 ");
                break;
            }
        }while(true);
    }

    // 写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入披萨种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}
/**
 * 北京的实例化类
 */
public class BJOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if(orderType.equals("cheese")){
            pizza = new BJCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new BJPepperPizza();
        }

        return pizza;
    }
}
/**
 * 伦敦的实例化类
 */
public class LDOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if(orderType.equals("cheese")){
            pizza = new LDCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new LDPepperPizza();
        }

        return pizza;
    }
}

3.3、商店类

/**
 * 商店类
 */
public class PizzaStore {
    public static void main(String[] args) {
//        new BJOrderPizza();
        new LDOrderPizza();
    }
}

三、抽象工厂模式

1、介绍

  1. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
  2. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
  3. 将工厂抽象成两层,AbsFactory(抽象工厂)和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和而扩展。

2、类图

3、例子

需求跟第二个一样。

3.1、披萨类

/**
 * 披萨类接口
 */
public abstract class 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;
    }
}
/**
 * 北京奶酪披萨
 */
public class BJCheesePizza extends Pizza {

    @Override
    public void prepare() {
        setName(" 北京的奶酪披萨 ");
        System.out.println(" 准备制作北京奶酪披萨 ");
    }
}
/**
 * 北京胡椒披萨
 */
public class BJPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 北京的胡椒披萨 ");
        System.out.println(" 准备制作北京胡椒披萨 ");
    }
}
/**
 * 伦敦奶酪披萨
 */
public class LDCheesePizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 伦敦的奶酪披萨 ");
        System.out.println(" 准备制作伦敦奶酪披萨 ");
    }
}
/**
 * 伦敦胡椒披萨
 */
public class LDPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName(" 伦敦的胡椒披萨 ");
        System.out.println(" 准备制作伦敦胡椒披萨 ");
    }
}

3.2、实例化类

/**
 * 实例化功能
 */
public class OrderPizza {
    AbsFactory factory;

    // 构造器
    public OrderPizza(AbsFactory factory){
        setFactory(factory);
    }

    public void setFactory(AbsFactory factory){
        Pizza pizza = null;
        String orderType = "";// 用户输入
        this.factory = factory;
        do{
            orderType = getType();
            // factory 可能是北京的工厂子类,也可能是伦敦的工厂子类
            pizza = factory.createPizza(orderType);
            if(pizza != null){
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
                System.out.println(" 订购失败 ");
                break;
            }
        }while(true);
    }

    // 写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入披萨种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

3.3、工厂类

/**
 * 工厂类接口
 */
public interface AbsFactory {
    //让下面的工厂子类来 具体实现
    public Pizza createPizza(String orderType);
}
/**
 * 北京工厂类
 */
public class BJFactory implements AbsFactory {

    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("~使用的是抽象工厂模式~");
        Pizza pizza = null;

        if(orderType.equals("cheese")){
            pizza = new BJCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new BJPepperPizza();
        }
        return pizza;
    }
}
/**
 * 伦敦工厂类
 */
public class LDFactory implements AbsFactory {
    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("~使用的是抽象工厂模式~");
        Pizza pizza = null;

        if(orderType.equals("cheese")){
            pizza = new LDCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

3.4、商店类

/**
 * 商店类
 */
public class PizzaStore {
    public static void main(String[] args) {
//        new OrderPizza(new BJFactory());
        new OrderPizza(new LDFactory());
    }
}
posted @ 2020-04-02 20:14  小燃、  阅读(185)  评论(0编辑  收藏  举报