简单工厂模式(静态工厂模式)

简单工厂模式介绍

简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式.。工厂模式有三种:1.简单工厂模式(静态工厂模式)  2.工厂方法模式  3.抽象工厂模式

 

先提一个需求不考虑设计模式

  披萨需求 :订阅很多披萨

 1.披萨有很多种类(GreekPizz,CheesePize)等

 2.披萨的制作方式 prepare(准备原材料),bake(烘焙),cut(切割),box(装盒) 

 3.完成披萨订购功能 

 

代码

 1.我会考虑先定义一个Pizza接口

package com.zjh.designmodel.factory.simplefactory;

/**
 * @Author: zjh
 * @Description: 披萨需求
 *   1.披萨有很多种类(GreekPizz,CheesePize)等
 *   2.披萨的制作方式 prepare(准备原材料),bake(烘焙),cut(切割),box(装盒)
 *   3.完成披萨订购功能
 * @Date: Created in 2020/4/28 14:14
 * Modified by:
 */
public interface Pizza {
    void prepare();
    void bake();
    void cut();
    void box();
}

2.我会让具体的披萨实现这个接口

package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/6 19:24
 * Modified by:
 */
public class CheesePize implements Pizza {
    @Override
    public void prepare() {
        System.out.println("CheesePize披萨原材料准备好了");
    }

    @Override
    public void bake() {
        System.out.println("CheesePize披萨已经烘焙好了");
    }

    @Override
    public void cut() {
        System.out.println("CheesePize披萨已经切割完成");
    }

    @Override
    public void box() {
        System.out.println("CheesePize披萨已经装盒了");
    }
}
package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/6 19:22
 * Modified by:
 */
public class GreekPizz implements Pizza {
    @Override
    public void prepare() {
        System.out.println("GreekPizz披萨原材料准备好了");
    }

    @Override
    public void bake() {
        System.out.println("GreekPizz披萨已经烘焙好了");
    }

    @Override
    public void cut() {
        System.out.println("GreekPizz披萨已经切割完成");
    }

    @Override
    public void box() {
        System.out.println("GreekPizz披萨已经装盒了");
    }
}

3.编写订单类

package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;

/**
 * @Author: zjh
 * @Description: 订购Pizz
 * @Date: Created in 2020/5/6 19:33
 * Modified by:
 */
public class OrderPizz {

    public OrderPizz(Pizza pizza) {
        if (pizza instanceof GreekPizz) {
            pizza = new GreekPizz();
        } else if (pizza instanceof CheesePize) {
            pizza = new CheesePize();
        } 
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    }
}

4.测试

简单工厂模式(静态工厂模式)_第1张图片

 

优点:

 比较好理解,简单易操作

缺点:

违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候尽量不修改代码。或者尽可能少的修改代码

我上面写的就有欠考虑,比如首先像烘焙,切割,装盒的操作其实都是一样的我们应该提出来,准备原材料这个方法可以让各自去实现所以就应该准备一个抽象类而不是接口,其次当你在增加一个披萨的时候你的订单类还要加一个elseif判断,如果你的订单类有很多那么你要改动的代码就更多了(这个地方就违反了上面的ocp原则,当我们增加披萨的时候应该尽量不去修改订单类)。所以就可以考虑下用简单工厂模式,让订单类通过我们的工厂类来创建披萨,这样我们就只需要修改工厂类就可以了

 

修改后的代码

简单工厂类

package com.zjh.designmodel.factory.simplefactory;

import com.zjh.designmodel.factory.simplefactory.impl.CheesePize;
import com.zjh.designmodel.factory.simplefactory.impl.GreekPizz;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/6 20:34
 * Modified by:
 */
public class SimpleFactoryPizza {
    public static Pizza createPizzaFactory(Integer pizzeType) {
        Pizza pizza = null;
        switch (pizzeType) {
            case 1:
                pizza = new GreekPizz();
                break;
            case 2:
                pizza = new CheesePize();
                break;
            default:
                break;
        }
        return pizza;
    }
}

修改后的披萨抽象类以及其子类

package com.zjh.designmodel.factory.simplefactory;

import org.springframework.util.StringUtils;

/**
 * @Author: zjh
 * @Description: 披萨需求
 *   1.披萨有很多种类(GreekPizz,CheesePize)等
 *   2.披萨的制作方式 prepare(准备原材料),bake(烘焙),cut(切割),box(装盒)
 *   3.完成披萨订购功能
 * @Date: Created in 2020/4/28 14:14
 * Modified by:
 */
public abstract class Pizza {
    protected String name;

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

    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+"披萨已经装盒了");
    }
}
package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/6 19:24
 * Modified by:
 */
public class CheesePize extends Pizza {
    @Override
    public void prepare() {
        System.out.println("CheesePizz披萨原材料准备好了");
        this.name="CheesePizz";
    }
}
package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;

/**
 * @Author: zjh
 * @Description:
 * @Date: Created in 2020/5/6 19:22
 * Modified by:
 */
public class GreekPizz extends Pizza {
    @Override
    public void prepare() {
        System.out.println("GreekPizz披萨原材料准备好了");
        this.name="GreekPizz";
    }
}

订单类

package com.zjh.designmodel.factory.simplefactory.impl;

import com.zjh.designmodel.factory.simplefactory.Pizza;
import com.zjh.designmodel.factory.simplefactory.SimpleFactoryPizza;

/**
 * @Author: zjh
 * @Description: 订购Pizz
 * @Date: Created in 2020/5/6 19:33
 * Modified by:
 */
public class OrderPizz {

//    public MethodOrderPizz(MethodPizza pizza) {
//        if (pizza instanceof MethodGreekPizz) {
//            pizza = new MethodGreekPizz();
//        } else if (pizza instanceof MethodCheesePize) {
//            pizza = new MethodCheesePize();
//        }
//        pizza.prepare();
//        pizza.bake();
//        pizza.cut();
//        pizza.box();
//    }

    public OrderPizz(){
    }
    //订披萨
    public void orderPizza(Integer pizzaType){
        Pizza pizzaFactory = SimpleFactoryPizza.createPizzaFactory(pizzaType);
        pizzaFactory.prepare();
        pizzaFactory.bake();
        pizzaFactory.cut();
        pizzaFactory.box();
    }

}

测试

简单工厂模式(静态工厂模式)_第2张图片

 

修改后的优点:

1.利用了抽象类减少冗余代码

2.利用工厂模式来创建对应的披萨实例,订单类就只关注披萨的种类不需要知道如何生成也就是说当我们在增加一个披萨种类的时候我们只需要在功工厂类加一个逻辑判断,订单类不做修改(解决了如果有多个订单类那么要修改的逻辑就会很多)。

修改后的缺点:

实例化对象的逻辑全部封装在一个工厂类里,每次需求变化都要单独修改工厂类(违反了开闭原则),对于新增的产品无能无力,这时候让我们看下工厂方法模式。

 

JDK源码用到的简单工厂模式(Calendar抽象类)

简单工厂模式(静态工厂模式)_第3张图片

 

总结

简单工厂模式包含三个角色工厂角色(SimpleFactory)负责实现创建所有实例的内部逻辑;抽象产品角色(Pizza)是所创建的所有对象的父类,负责描述所有实例所共有的公共接口;具体产品角色(GreekPizza)是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。
简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心。

 

你可能感兴趣的:(设计模式)