设计模式之简单工厂模式

定义:

  1. 简单工厂模式属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式是工厂模式家族最简单实用的模式。
  2. 定义了一个创建对象的类,由这个类封装实例化对象的行为。
  3. 在软件开发中,当我们会用到大量的创建某种、某类、或者某批对象时,就会使用到工厂模式。

场景:一个关于pizza的项目。
4. pizza的种类很多,GreekPizza、CheesePizza等。
5. Pizza的制作流程:prepare、bake、cut、box。
6. 完成披萨店的订购功能。

第一版UML图及代码:
在这里插入图片描述

public abstract class Pizza {

    protected String name;

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

    /**
     * 每种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 class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(name + " 在准备制作的原材料。");
    }
}

public class CheesePizza extends Pizza {

    @Override
    public void prepare() {
        System.out.println(name + " 在准备制作的原材料。");
    }
}

public class PizzaOrder {

    public void addOrder(){

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Pizza pizza = null;
        while (true){
            try {
                String name = reader.readLine();
                if ("cheese".equalsIgnoreCase(name)){
                    pizza = new CheesePizza();
                    pizza.setName("奶酪披萨");
                }
                else if ("greek".equalsIgnoreCase(name)){
                    pizza = new GreekPizza();
                    pizza.setName("希腊披萨");
                }
                else {
                    break;
                }
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        PizzaOrder order = new PizzaOrder();
        order.addOrder();
    }
}

//第一版分析:
//1. 将制作披萨的流程实现在调用方PizzaOrder 中,假如新增一种SaladPizza,就要修改调用方PizzaOrder 的代码,如果有多个PizzaOrder ,就使得系统更加地复杂。这就违反了开闭原则。对修改进行开放了。
			    if ("cheese".equalsIgnoreCase(name)){
                    pizza = new CheesePizza();
                    pizza.setName("奶酪披萨");
                }
                else if ("greek".equalsIgnoreCase(name)){
                    pizza = new GreekPizza();
                    pizza.setName("希腊披萨");
                }
                else if ("Salad".equalsIgnoreCase(name)){
                    pizza = new SaladPizza();
                    pizza.setName("沙拉披萨");
                }
                

第二版(使用简单工厂模式)的UML及代码:
在这里插入图片描述

public abstract class Pizza {

    protected String name;

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

    /**
     * 每种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 class GreekPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println(name + " 在准备制作的原材料。");
    }
}

public class CheesePizza extends Pizza {

    @Override
    public void prepare() {
        System.out.println(name + " 在准备制作的原材料。");
    }
}

public class PizzaFactory {

    public Pizza createPizza(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Pizza pizza = null;
        while (true){
            try {
                String name = reader.readLine();
                if ("cheese".equalsIgnoreCase(name)){
                    pizza = new CheesePizza();
                    pizza.setName("奶酪披萨");
                }
                else if ("greek".equalsIgnoreCase(name)){
                    pizza = new GreekPizza();
                    pizza.setName("希腊披萨");
                }
                else {
                    break;
                }
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
                return pizza;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return pizza;
    }
}
public class PizzaOrder {

    private PizzaFactory pizzaFactory = new PizzaFactory();

    public void addOrder(){
        Pizza pizza = pizzaFactory.createPizza();
    }

    public static void main(String[] args) {
        PizzaOrder order = new PizzaOrder();
        order.addOrder();
    }
}

//分析:这个代码使用了简单工厂模式进行改进,将制作pizza的细节封装在了工厂中,
//调用方PizzaOrder 无需知道细节,只管调用PizzaFactory.createPizza()就可以获得想要的
//pizza。当新增一种pizza时,只需要修改工厂,无需修改调用方PizzaOrder ,符合开闭原则。

静态工厂是一种特殊的简单工厂,实现代码:

public class PizzaFactory {

    public **static** Pizza createPizza(){
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        Pizza pizza = null;
        while (true){
            try {
                String name = reader.readLine();
                if ("cheese".equalsIgnoreCase(name)){
                    pizza = new CheesePizza();
                    pizza.setName("奶酪披萨");
                }
                else if ("greek".equalsIgnoreCase(name)){
                    pizza = new GreekPizza();
                    pizza.setName("希腊披萨");
                }
                else {
                    break;
                }
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
                return pizza;
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return pizza;
    }
}

简单工厂模式适用于类比我是很多,并且不会经常增加新的类别,比如如果Pizza经常退出新品,或者品类很多,就不太适合使用简单工厂模式,因为每增加一种类别,就要修改工厂类的代码,违反了开闭原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值