工厂模式的由来,简单(静态)工厂、工厂方法模式的详解

订购Pizza

pizza种类 ——客户端——pizza店
传统解决方案类图为
工厂模式的由来,简单(静态)工厂、工厂方法模式的详解_第1张图片
可以看到OrderPizza (客户端)依赖了每一种pizza 这样造成了 如果添加一种或者修改一种pizza那就会造成每个客户端需要修改,如果客户端特比多那就是灾难了。

package Factory.Pizza;

//披萨抽象类
public abstract class Pizza
{
    protected String name; //pizza名字
    //准备pizza 不同的pizza 准备的不同
    public abstract void prepare();

    public void bake()
    {
        System.out.println("正在烘烤"+name);
    }

    public void cut()
    {
        System.out.println("正在切割"+name);
    }

    public void box()
    {
        System.out.println("正在打包"+name);
    }

    public void setName(String name)
    {
            this.name = name;
    }
}

package Factory.Pizza;
//定义奶酪披萨
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("准备奶酪");
    }
}

package Factory.Order;

import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderPizza
{
    Pizza pizza =null;
    String PizzaType;//说明订购Pizza类型
    //检测订购类型
    public OrderPizza()
    {
        do {
            PizzaType=getPizzaType();
            if(PizzaType.equals("greek"))
            {
                pizza = new GreekPizza();
                pizza.setName("greekpizza");
            }
            else if(PizzaType.equals("cheese"))
            {
                pizza = new CheesePizza();
                pizza.setName("cheesepizza");
            }
            else if(PizzaType.equals("pepper"))
            {
                pizza = new PepperPizza();
                pizza.setName("pepperpizza");
            }
            else {
                break;
            }
            System.out.println("已接单");
            pizza.prepare();
            pizza.cut();
            pizza.bake();
            pizza.box();
        } while(true);
    }

    //模拟客户端选择pizza
    private String getPizzaType()
    {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("输入pizza类型");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}

package Factory.Store;

import Factory.Order.OrderPizza;

public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza();
    }
}

改进思路

使用简单工厂。那么我们需要把创建pIzza对象封装成一个类,只需要对其修改就可以了。
工厂模式的由来,简单(静态)工厂、工厂方法模式的详解_第2张图片

首先创建一个工厂 用来创造对象

package Factory.Order;

import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;

public class SimpleFactory
{
    public Pizza createPizza(String PizzaType){
        System.out.println("简单工厂造出");
        Pizza pizza =null;
        System.out.println("正在启动工厂");
        if(PizzaType.equals("greek"))
        {
            pizza = new GreekPizza();
            pizza.setName("greekpizza");
        }
        else if(PizzaType.equals("cheese"))
        {
            pizza = new CheesePizza();
            pizza.setName("cheesepizza");
        }
        else if(PizzaType.equals("pepper"))
        {
            pizza = new PepperPizza();
            pizza.setName("pepperpizza");
        }
        return pizza;
    }
}

修改客户端的类

package Factory.Order;

import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderPizza
{
    Pizza pizza =null;
    String PizzaType;//说明订购Pizza类型
    //引用简单工厂对象
    SimpleFactory simpleFactory;

    public OrderPizza(SimpleFactory simpleFactory){
        setFactory(simpleFactory);
    }

    //获取工厂的创造的对象
    public void setFactory(SimpleFactory simpleFactory){
        this.simpleFactory=simpleFactory;
        do {
            PizzaType = getPizzaType();
            pizza=this.simpleFactory.createPizza(PizzaType);
            if(pizza !=null){
                System.out.println("订单成功");
                pizza.prepare();
                pizza.cut();
                pizza.bake();
                pizza.box();
            }
            else {
                System.out.println("订单失败");
                break;
            }
        }while (true);
    }

    //模拟客户端选择pizza
    private String getPizzaType()
    {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("输入pizza类型");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}

商店重新调用

package Factory.Store;

import Factory.Order.OrderPizza;
import Factory.Order.SimpleFactory;

public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new SimpleFactory());
        System.out.println("---------程序退出---------");
    }
}

小结:如果需要静态工厂 需要把工厂里的创建对象的方法设置成静态的,这样其他类可以直接可以通过类名.方法名进行调用,不需要引用成员等操作。
故简单工厂也为静态工厂。

需求改动升级

因为客户需求,现在要求 增加不同的工厂,有北京有工厂,伦敦也要有工厂,如果继续按简单工厂持续创作工厂,那样会使得工厂创建过于多。
从而引出升级模式——工厂方法模式
具体类图如下。
工厂模式的由来,简单(静态)工厂、工厂方法模式的详解_第3张图片
抽象工厂模式
工厂模式的由来,简单(静态)工厂、工厂方法模式的详解_第4张图片
如图所示就是把工厂定义为接口,然后定义两个工厂去实现。在最后,使用OrderPizza将其聚合即可
抽象工厂与方法工厂代码样式差不错。这里举例抽象工厂。
**pizza 的实现类分为北京胡椒、天津胡椒。**如下图。
工厂模式的由来,简单(静态)工厂、工厂方法模式的详解_第5张图片
定义个工厂接口

package Factory.AbsFactory.Order;

import Factory.AbsFactory.AbsPizza.AbsPizza;

public interface AbsFactory
{
    public AbsPizza creatPizza(String pizzaType);
}

不同的工厂来实现 并创建不同的pizza对象

package Factory.AbsFactory.Order;

import Factory.AbsFactory.AbsPizza.AbsPizza;
import Factory.AbsFactory.AbsPizza.BJCheesePizza;

public class BJFactory implements AbsFactory
{

    @Override
    public AbsPizza creatPizza(String pizzaType) {
        System.out.println("北京工厂启动ing");
        AbsPizza absPizza = null;
        if (pizzaType.equals("cheese")){
            absPizza=new BJCheesePizza();
        }
        else if(pizzaType.equals("pepper")){
            absPizza=new BJCheesePizza();
        }
        return absPizza;

    }
}

在客户端上选择工厂、Pizza

package Factory.AbsFactory.Order;

import Factory.AbsFactory.AbsPizza.AbsPizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class ChoiseFactory
{
    public ChoiseFactory(AbsFactory factory){
        setFactory(factory);
    }
    AbsFactory factory;
    public void setFactory(AbsFactory factory){
        this.factory=factory;
        AbsPizza absPizza = null;
        String pizzaType = "";
        do {
            pizzaType = getPizzaType();
            //由于factory 为接口类,所以factory可以是子类工厂任何一个
            absPizza= factory.creatPizza(pizzaType);
            if(absPizza !=null){
                System.out.println("订单成功");
                absPizza.prepare();
                absPizza.cut();
                absPizza.bake();
                absPizza.box();
            }
            else {
                System.out.println("订单失败");
                break;
            }
        }while (true);

    }

    private String getPizzaType()
    {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("输入pizza类型");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

最后在商店里调用具体哪个工厂的接口即可

package Factory.AbsFactory.Order;

public class PizzaStore {
    public static void main(String[] args) {
        new ChoiseFactory(new BJFactory());
    }
}

你可能感兴趣的:(笔记)