简单工厂模式(Simple Factory Pattern)

目录

 

1、需求

2、传统方式解决问题

2.1、类图

2.2、代码

2.3、传统方式解决问题分析

2.4、改进的思路分析

3、简单工厂模式

3.1、基本介绍

3.2、简单工厂模式解决问题

3.2.1、分析

3.2.2、类图

3.2.3、代码

3.2.4、简单工厂实现分析

4、简单工厂模式优缺点分析

5、使用场景


1、需求

一个牛奶项目:

  • 牛奶有很多种:甜牛奶(SweetMilk)、酸牛奶(SourMilk)等。
  • 制作牛奶有:准备鲜牛奶(prepareMilk)、高温杀菌(pasteurize)、打包装(package)。
  • 在高温杀菌的步骤可以加入不同的配料制作不同的牛奶。
  • 编程完成牛奶订购功能。

2、传统方式解决问题

2.1、类图

 

2.2、代码

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        //来一份甜牛奶和两份酸牛奶
        String[] types = {"sweet","sour","sour"};
        new Order(types);
    }
}

/**
 * 牛奶抽象类
 */
abstract class Milk{
    private String name;
    public void prepareMilk(){
        System.out.println("准备新鲜的牛奶");
    }

    /**
     * 高温杀菌
     */
    public abstract void pasteurize();

    public void packaging(){
        System.out.println("将"+name+"打包装");
    }

    public String getName() {
        return name;
    }

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

/**
 * 甜牛奶
 */
class SweetMilk extends Milk{

    /**
     * 高温杀菌
     */
    @Override
    public void pasteurize() {
        System.out.println("高温杀菌,加入糖");
    }
}

/**
 * 酸牛奶
 */
class SoutMilk extends Milk{

    /**
     * 高温杀菌
     */
    @Override
    public void pasteurize() {
        System.out.println("高温杀菌,加入果酸");
    }
}

/**
 * 订单
 */
class Order{
    /**
     * 构造器
     * @param types  多份牛奶的类型
     */
    public Order(String...types){
        for(String type:types){
            Milk milk = null;
            if("sweet".equals(type)){
                milk = new SweetMilk();
                milk.setName("甜牛奶");
            }else if("sour".equals(type)){
                milk = new SoutMilk();
                milk.setName("酸牛奶");
            }

            //输出牛奶制作过程
            System.out.println("---------------"+milk.getName()+"制作过程------------");
            milk.prepareMilk();
            milk.pasteurize();
            milk.packaging();
            System.out.println();
        }
    }
}

运行结果:

2.3、传统方式解决问题分析

优点:比较好理解,简单易操作

缺点:违反了设计模式的ocp原则(即对扩展开放,对修改关闭)

比如我们现在如果要新增一种牛奶:核桃牛奶(WalnutMilk)

  • 先要编写一个WalnutMilk类继承Milk并实现其抽象方法
/**
 * 核桃奶类
 */
class WalnutMilk extends Milk{

    /**
     * 高温杀菌
     */
    @Override
    public void pasteurize() {
        System.out.println("高温杀菌,加入核桃粉");
    }
}
  • 然后要在订单类Order中新增if-else来判断核桃牛奶(违反了ocp原则)
...
else if("walnut".equals(type)){
    milk = new WalnutMilk();
    milk.setName("核桃奶");
}
...

2.4、改进的思路分析

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

3、简单工厂模式

3.1、基本介绍

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

3.2、简单工厂模式解决问题

3.2.1、分析

设计方案:定义一个可以实例化的Milk对象的类,封装创建对象的代码

3.2.2、类图

3.2.3、代码

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        //来一份甜牛奶和两份酸牛奶
        SimpleFactory simpleFactory = new SimpleFactory();
        String[] types = {"sweet","sour","sour"};
        new Order(simpleFactory,types);
    }
}

/**
 * 牛奶抽象类
 */
abstract class Milk{
    private String name;
    public void prepareMilk(){
        System.out.println("准备新鲜的牛奶");
    }

    /**
     * 高温杀菌
     */
    public abstract void pasteurize();

    public void packaging(){
        System.out.println("将"+name+"打包装");
    }

    public String getName() {
        return name;
    }

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

/**
 * 甜牛奶
 */
class SweetMilk extends Milk {

    /**
     * 高温杀菌
     */
    @Override
    public void pasteurize() {
        System.out.println("高温杀菌,加入糖");
    }
}

/**
 * 酸牛奶
 */
class SoutMilk extends Milk {

    /**
     * 高温杀菌
     */
    @Override
    public void pasteurize() {
        System.out.println("高温杀菌,加入果酸");
    }
}

/**
 * 订单
 */
class Order{
    private SimpleFactory simpleFactory;
    /**
     * 构造器
     * @param types  多份牛奶的类型
     */
    public Order(SimpleFactory simpleFactory,String...types){
        this.simpleFactory = simpleFactory;
        for(String type:types){
            //从工厂中获取牛奶对象
            Milk milk = simpleFactory.createMilk(type);
            //输出牛奶制作过程
            System.out.println("---------------"+milk.getName()+"制作过程------------");
            milk.prepareMilk();
            milk.pasteurize();
            milk.packaging();
            System.out.println();
        }
    }
}

/**
 * 工厂
 */
class SimpleFactory{
    public Milk createMilk(String type){
        Milk milk = null;
        if("sweet".equals(type)){
            milk = new SweetMilk();
            milk.setName("甜牛奶");
        }else if("sour".equals(type)){
            milk = new SoutMilk();
            milk.setName("酸牛奶");
        }
        return milk;
    }

运行结果和上面的一样。

3.2.4、简单工厂实现分析

现在如果要增加一种新的牛奶:核桃牛奶

  • 创建核桃牛奶类
  • 修改工厂中的逻辑代码if-else即可(不需要修改订单类Order,符合ocp原则)。

4、简单工厂模式优缺点分析

优点:

  • 工厂类是整个模式的关键,包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象;
  • 通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的,明确了各自的职责和权利,有利于整个软件体系结构的优化。

缺点:

  • 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;
  • 它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
  • 当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求,这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
  • 这些缺点在工厂方法模式中得到了一定的克服。

5、使用场景

  • 工厂类负责创建的对象比较少;
  • 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
  • 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值