设计模式-简单工厂模式

概述

  • 定义 : 由一个工厂对象决定创建出哪一种产品类的实例
  • 类型 : 创建型, 但不属于GOF23种设计模式

适用场景

  • 工厂类负责创建的对象比较少
  • 客户端(应用层)只知道传入工厂的参数对于如何创建对象不关心

优点

  • 只需要传入一个正确的参数, 就可以获取你所需要的对象而无需知道其创建细节

缺点

  • 工厂类的职责相对过重, 增加新的产品需要修改工厂类的判断逻辑, 违背开闭原则

代码演示

  • 有一个果汁工厂, 可以生产各种果汁, 对应工厂类, 根据传入的果汁名称生产各种果汁
  • 一个果汁的接口Juice, 里面只有一个方法, 用于展示果汁名称
  • 各种果汁的实现类, 代码如下:
    工厂类 :
/**
 * 简单工厂模式
 * 果汁工厂类
 *
 * @author 七夜雪
 * @create 2018-11-22 10:14
 */
public class JuiceFactory {
    public Juice getJuice(String name){
        if ("apple".equalsIgnoreCase(name)) {
            return new AppleJuice();
        } else if ("orange".equalsIgnoreCase(name)){
            return new OrangeJuice();
        }
        return null;
    }
}

果汁接口 :

/**
 * 果汁接口类
 * @author 七夜雪
 * @create 2018-11-22 10:15
 */
public interface Juice {
    public String showName();;
}

苹果汁实现类 :

/**
 * 苹果汁
 *
 * @author 七夜雪
 * @create 2018-11-22 10:17
 */
public class AppleJuice implements Juice {
    @Override
    public String showName() {
        return "苹果汁";
    }
}

橙汁实现类:

/**
 * 橙汁
 *
 * @author 七夜雪
 * @create 2018-11-22 10:15
 */
public class OrangeJuice implements Juice {
    @Override
    public String showName() {
        return "橙汁";
    }
}

上面的代码就展示了一个简单工厂, 但是现在如果需要再增加新的果汁种类, 就必须修改工厂类, 违反了开闭原则, 比如说, 现在增加了一种西瓜汁, 所以可以使用反射对简单工厂做一些扩展, 增加了反射获取的方法, 修改后的工厂类代码如下 :

/**
 * 简单工厂模式
 * 果汁工厂类
 *
 * @author 七夜雪
 * @create 2018-11-22 10:14
 */
public class JuiceFactory {
	// 有时候可以将方法设置成静态方法, 使用时就不用再new 一个factory对象了
    public Juice getJuice(String name){
        if ("apple".equalsIgnoreCase(name)) {
            return new AppleJuice();
        } else if ("orange".equalsIgnoreCase(name)){
            return new OrangeJuice();
        }
        return null;
    }

    /**
     * 使用反射扩展简单工厂模式
     * @param clazz
     * @return
     */
    public Juice getJuice(Class<? extends Juice> clazz){
        Juice juice = null;
        try {
            juice = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return juice;
    }

}

西瓜汁类代码:

/**
 * 西瓜汁
 *
 * @author 七夜雪
 * @create 2018-11-22 10:23
 */
public class WatermelonJuice implements Juice {
    @Override
    public String showName() {
        return "西瓜汁";
    }
}

测试类代码:

/**
 * 简单工厂测试类
 *
 * @author 七夜雪
 * @create 2018-11-22 10:23
 */
public class Test {

    public static void main(String[] args) {
        JuiceFactory factory = new JuiceFactory();
        Juice juice;
        juice = factory.getJuice("apple");
        System.out.println(juice.showName());
        // 使用反射扩展可以不用直接修改工厂类
        juice = factory.getJuice(WatermelonJuice.class);
        System.out.println(juice.showName());
    }
}

上面代码的整体UML类图如下 :
在这里插入图片描述

注 : 上面这个类图是使用IntelliJ IDEA的自动生成的UML类图, 一个很好用的功能

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值