Java design pattern----factory pattern-----simple factory (static factory pattern)

Factory mode

Let’s look at a specific requirement first

Look at a pizza project: To facilitate the expansion of pizza types, and to facilitate maintenance
1) There are many types of pizza (such as GreekPizz (Greek), CheesePizz (cheese), etc.)
2) Pizza is made with prepare (preparation material), bake (baking) Bake), cut (cut), box (packed)
3) Complete the pizzeria ordering function.

How to do it in the traditional way?

Insert picture description here

Code

Pizza abstract class

/**
 * @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;
    }
}

Two different types of 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("给希腊披萨准备原材料");
    }
}

Order initiation class

/**
 * @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 "";
        }
    }
}

Main category: Pizza shop

/**
 * @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();
    }
}

Advantages and problems

The advantage is that it is easier to understand and easy to operate.
The disadvantage is that it violates the ocp principle of the design pattern, that is, it is open for extension and closed for modification . That is, when we add new functions to the class, try not to modify the code, or modify the code as little as possible

For example, if we want to add a new type of Pizza (Pepper Pizza) at this time, we need to make the following changes:

1. Add pepper pizza, inherit the abstract pizza class

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

2. We must add the logic of judging whether it is pepper pizza or not in 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;
}

Many branches have joined us, and there are 2,3,4,5,6...How about OrderPizza? Doesn't everything have to be changed?

Improve

Analysis : Modifying the code is acceptable, but if we also have the code for creating Pizza in other places, it means that we also need to modify, and there are often many places to create the code for Pizza.
**Idea:** Encapsulate the created Pizza object into a class, so that when we have a new Pizza category, we only need to modify the class, and other codes created to the Pizza object do not need to be modified === => Simple Factory Mode

Simple factory pattern

basic introduction

Static factory mode

1) The simple factory model belongs to the creation model , which is a kind of factory model. The simple factory pattern is that a factory object determines which instance of a product class is created . Simple factory mode is the simplest and most practical mode in the factory mode family

2) Simple factory pattern: defines a class for creating objects, and this class encapsulates the behavior of instantiated objects (code)

3) In software development, when we will use a large number of objects to create a certain type, a certain type or a certain batch of objects, the factory model will be used .

Insert picture description here

Code

/**
 * @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;
    }
}

Changes in 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 "";
        }
    }

}

Client changes

/**
 * @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("退出程序");
    }
}

Let's understand: First of all, we new codes of different types of Pizza, transferred from OrderPizza to simple factory mode, so that when we need to increase the types of pizza in the future, we don't have to worry about so many OrderPizza, just need to be in the factory mode. Just add a logical judgment, and this factory is an extension , in line with our OOP thinking

In our OrderPizza, a direct friend simple factory object is introduced. This simple factory object produces Pizza for us. Our OrderPizza only needs to get this object. It does not need to go to new by itself. It is in accordance with the modification and closure.

More convenient is that we can set the createPizza method in the simple factory pattern as a static method. What will our code become?

The change of the simple factory model is just to add static modification to the createPizza method

OrderPizza changes

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 "";
        }
    }
}

Because our createPizza has become static mode, we don’t need to pass a simple factory object, we can call it directly by the class name, and we don’t need to set a simple factory object anymore.

The difference between the two is not big, the details are that when it is not a static method, it is easy to create according to the needs, and the effect is not much different, depending on the business needs

Guess you like

Origin blog.csdn.net/qq_22155255/article/details/111500028
Recommended