Java设计模式----工厂模式-----简单工厂(静态工厂模式)

工厂模式

我们先看一个具体需求

看一个披萨的项目:要便于披萨种类的扩展,要便于维护
1)披萨的种类很多(比如GreekPizz(希腊)、CheesePizz (奶酪)等)
2)披萨的制作有prepare(准备材料), bake(烘烤), cut(切割), box(打包)
3)完成披萨店订购功能。

传统方式怎么做?

在这里插入图片描述

代码

Pizza抽象类

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:06
 * @Description TODO
 * @pojectname 披萨抽象类    设置为抽象类
 */
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;
    }
}

两种不同的Pizza种类

public class CheesePizza extends Pizza {
    
    
    @Override
    public void prepare() {
    
    
        System.out.println("准备制作奶酪披萨的原材料");
    }
}
public class GreekPizza extends Pizza {
    
    
    @Override
    public void prepare() {
    
    
        System.out.println("给希腊披萨准备原材料");
    }
}

订单发起类

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:14
 * @Description TODO
 * @pojectname 订购披萨代码
 */
public class OrderPizza {
    
    
    //构造器

    public OrderPizza() {
    
    
        Pizza pizza = null;
        String orderType;//订购披萨类型是什么
        do {
    
    
            orderType = getType();
            if (orderType.equals("greek")){
    
    
                pizza = new GreekPizza();
                pizza.setName("希腊披萨");
            }else if (orderType.equals("cheese")){
    
    
                pizza = new CheesePizza();
                pizza.setName("奶酪披萨");

            }else {
    
    
                break;
            }
            //输出pizza制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }while (true);
    }

    //获取客户订购的披萨种类
    private String getType(){
    
    
        try {
    
    
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza 种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "";
        }
    }
}

主类:披萨店

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:22
 * @Description TODO
 * @pojectname 披萨店客户端,发起订购的类(主类)
 */
public class PizzaStore {
    
    
    public static void main(String[] args) {
    
    
        OrderPizza orderPizza = new OrderPizza();
    }
}

优点和存在的问题

优点是比较好理解,简单易操作。
缺点是违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码

比如我们这时要新增加一个Pizza的种类(Pepper披萨),我们需要做如下修改:

1.增加胡椒披萨,继承抽象披萨类

public class PepperPizza extends Pizza {
    
    
    @Override
    public void prepare() {
    
    
        System.out.println("给胡椒披萨准备原材料");
    }
}

2.我们就必须在OrderPizza中加入判断是不是胡椒披萨的逻辑

if (orderType.equals("greek")){
    
    
    pizza = new GreekPizza();
    pizza.setName("希腊披萨");
}else if (orderType.equals("cheese")){
    
    
    pizza = new CheesePizza();
    pizza.setName("奶酪披萨");
}else if (orderType.equals("pepper")){
    
    
    pizza = new PepperPizza();
    pizza.setName("胡椒披萨");
} else {
    
    
    break;
}

加入我们分店多,OrderPizza有2,3,4,5,6……呢?岂不是每个都要改?

改进

分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处。
**思路:**把创建Pizza对象封装到-一个类中,这样我们有新的Pizza种类时,只需要修改该类就可,其它有创建到Pizza对象的代码就不需要修改了====>简单工厂模式

简单工厂模式

基本介绍

又称静态工厂模式

1)简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产 品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式

2)简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

3)在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.

在这里插入图片描述

代码

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:43
 * @Description TODO
 * @pojectname 简单工厂用来管理Pizza的生产
 */
public class SimpleFactory {
    
    
    /**
     * 根据我们的pizza类型,返回一个该类型的实例对象
     * @param orderType pizza类型
     * @return
     */
    public Pizza createPizza(String orderType){
    
    
        Pizza pizza = null;
        System.out.println("使用简单工厂模式");
        if (orderType.equals("greek")){
    
    
            pizza = new GreekPizza();
            pizza.setName("希腊披萨");
        }else if (orderType.equals("cheese")){
    
    
            pizza = new CheesePizza();
            pizza.setName("奶酪披萨");
        }else if (orderType.equals("pepper")){
    
    
            pizza = new PepperPizza();
            pizza.setName("胡椒披萨");
        }
        return pizza;
    }
}

OrderPizza的变化

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:14
 * @Description TODO
 * @pojectname 订购披萨代码
 */
public class OrderPizza {
    
    
    //定义简单工厂对象
    SimpleFactory simpleFactory;
    Pizza pizza = null;
    public void setSimpleFactory(SimpleFactory simpleFactory) {
    
    
        String orderType = "";//orderType用户输入pizza类型
        this.simpleFactory = simpleFactory;//设置一个简单工厂对象
        do {
    
    
            orderType = getType();//获取用户订购的pizza类型
            pizza = this.simpleFactory.createPizza(orderType);
            //输出制作pizza信息
            if (pizza != null){
    
    
                //订购成功
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
    
    
                System.out.println("预定失败,请检查是不是没有这个pizza类型");
                break;
            }
        }while(true);
    }
    //构造器
    public OrderPizza(SimpleFactory simpleFactory){
    
    
        setSimpleFactory(simpleFactory);
    }
    
    //获取客户订购的披萨种类
    private String getType(){
    
    
        try {
    
    
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza 种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "";
        }
    }

}

客户端的变化

/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:22
 * @Description TODO
 * @pojectname 披萨店客户端,发起订购的类(主类)
 */
public class PizzaStore {
    
    
    public static void main(String[] args) {
    
    
       //使用简单工厂模式订购
        new OrderPizza(new SimpleFactory());
        System.out.println("退出程序");
    }
}

我们来理解一下:首先我们new不同Pizza种类的代码,从OrderPizza中转移到了简单工厂模式,这样以后我们还要增加披萨种类的时候,就不用去管那么多的OrderPizza了,只需要在工厂模式中增加一个逻辑判断就行了,而且这个工厂是扩展方,符合了我们OOP的思想

在我们的OrderPizza中,引入了一个直接朋友简单工厂对象,由这个简单工厂对象给我们生产Pizza,我们的OrderPizza只需要拿到这个对象就行了,并不需要自己再去new了,符合修改关闭

更加方便的是,我们可以把简单工厂模式中的createPizza方法设置为静态方法,那我们的代码会变成什么呢?

简单工厂模式的变化只是把createPizza方法加static修饰

OrderPizza改变

package com.wang.factory.pizza.order;
import com.wang.factory.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
 * @author 王庆华
 * @version 1.0
 * @date 2020/12/21 20:14
 * @Description TODO
 * @pojectname 订购披萨代码
 */
public class OrderPizza2 {
    
    
    Pizza pizza = null;
    String orderType = "";//orderType用户输入pizza类型
    //构造器
    public OrderPizza2(){
    
    
        do {
    
    
            orderType = getType();//获取用户订购的pizza类型
            pizza = SimpleFactory.createPizza(orderType);
            //输出制作pizza信息
            if (pizza != null){
    
    
                //订购成功
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
    
    
                System.out.println("预定失败,请检查是不是没有这个pizza类型");
                break;
            }
        }while(true);
    }
    //获取客户订购的披萨种类
    private String getType(){
    
    
        try {
    
    
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza 种类:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return "";
        }
    }
}

因为我们的createPizza变成静态模式了,我们就不需要在传递一个简单工厂对象了,可以直接通过类名调用,就不在需要set一个简单工厂对象了

两者差距不大,细节之处在于不是静态方法的时候,容易根据需求creat,效果相差不大,看业务需求

猜你喜欢

转载自blog.csdn.net/qq_22155255/article/details/111500028