概述
- 定义 : 由一个工厂对象决定创建出哪一种产品类的实例
- 类型 : 创建型, 但不属于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类图, 一个很好用的功能