文章目录
- 一、简单工厂模式简介
- 二、简单工厂模式适用场景
- 三、简单工厂模式优缺点
- 四、简单工厂模式代码示例
- 1、抽象类
- 2、子类对象 1
- 3、子类对象 2
- 4、工厂类
- 5、测试类
一、简单工厂模式简介
简单工厂模式 : 由 一个 工厂对象 决定 创建出 哪一种 产品类 的 实例 ;
简单工厂模式类型 : 创建型 ;
二、简单工厂模式适用场景
简单工厂模式适用场景 :
- 创建对象少 : 工厂类 负责 创建的对象 比较少 ;
- 不关心创建过程 : 客户端 只知道 传入 工厂类 的参数 , 对于 如何创建对象 不关心 ;
三、简单工厂模式优缺点
简单工厂模式优点 : 只需要传入 正确的参数 , 就可以 获取需要的对象 , 无需知道创建细节 ; 工厂类中有必要的 判断逻辑 , 可以决定 根据当前的参数 创建对应的产品实例 , 客户端可以免除直接创建产品对象的责任 ; 通过该模式 , 实现了对 创建实例 和 使用实例 的 责任分割 ; 提供专门的 工厂类 用于创建对象 , 客户端 无需知道所创建的产品类的类名 , 只需要知道对应产品类的参数即可创建对象实例 ;
简单工厂模式缺点 : 工厂类 职责 过重 , 如果要增加新的产品 , 需要 修改工厂类的判断逻辑 , 违背 " 开闭原则 " ;
大设计原则 , 不能全部遵守 , 也不能不遵守 , 注意平衡 功能 和 系统复杂度 , 找到最合适的一个点 ;
四、简单工厂模式代码示例
1、抽象类
代码语言:javascript复制package simplefactory;
/**
* 视频抽象
*/
public abstract class Vedio {
/**
* 生产视频
*/
public abstract void produce();
}
2、子类对象 1
代码语言:javascript复制package simplefactory;
public class JavaVedio extends Vedio {
@Override
public void produce() {
System.out.println("录制 Java 视频");
}
}
3、子类对象 2
代码语言:javascript复制package simplefactory;
public class PythonVedio extends Vedio {
@Override
public void produce() {
System.out.println("录制 Python 视频");
}
}
4、工厂类
简单工厂模式的缺点 : 如果要增加新的课程如 C 课程 , 就需要修改 getVedio 方法 , 在该方法中添加新的分支 , 明显该操作违反了开闭原则 , 对扩展开方 , 对修改关闭 , 只要修改就会带来风险 ;
使用传入 Class 参数的方法 , 可以解决上述问题 , 如果要扩展 , 只需要传入不同的 Class 类即可 , 不需要修改工厂方法 ;
代码示例 :
代码语言:javascript复制package simplefactory;
/**
* 简单工厂模式的缺点 :
* 如果要增加新的课程如 C 课程 , 就需要修改 getVedio 方法
* 在该方法中添加新的分支
* 明显该操作违反了开闭原则 , 对扩展开方 , 对修改关闭
* 只要修改就会带来风险
*
* 使用传入 Class 参数的方法 , 可以解决上述问题 , 如果要扩展
* 只需要传入不同的 Class 类即可
*/
public class VedioFactory {
/**
* 根据传入的参数 , 创建不同的 Vedio 子类实例对象
* 该方法不符合开闭原则
* 如果增加新的 Vedio 子类 , 需要修改本方法 , 增加新的分支
* @param type
* @return
*/
public Vedio getVedio(String type) {
Vedio vedio = null;
if ("Java".equals(type)) {
vedio = new JavaVedio();
} else if ("Python".equals(type)) {
vedio = new PythonVedio();
}
return vedio;
}
/**
* 根据传入的参数 , 创建不同的 Vedio 子类实例对象
* 该方法符合开闭原则
* 如果增加新的 Vedio 子类 , 不需要修改本方法
* @param clazz
* @return
*/
public Vedio getVedio(Class<?> clazz) {
Vedio vedio = null;
// 通过反射创建对象
try {
vedio = (Vedio) Class.forName(clazz.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return vedio;
}
}
5、测试类
代码语言:javascript复制package simplefactory;
public class Main {
public static void main(String[] args) {
// 如果直接创建 JavaVedio
// 那么本类需要依赖 JavaVedio , 即导入 JavaVedio 依赖
Vedio javaVedio = new JavaVedio();
javaVedio.produce();
// 如果直接创建 PythonVedio
// 那么本类需要依赖 PythonVedio , 即导入 PythonVedio 依赖
Vedio pythonVedio = new PythonVedio();
pythonVedio.produce();
System.out.println();
// 使用工厂类 , 可以避免直接依赖被创建的类
// 不管创建多少种类的实例对象 , 只需要依赖一个工厂类即可
Vedio javaVedio2 = new VedioFactory().getVedio("Java");
javaVedio2.produce();
Vedio pythonVedio2 = new VedioFactory().getVedio("Python");
pythonVedio2.produce();
}
}
执行结果 :
代码语言:javascript复制录制 Java 视频
录制 Python 视频
录制 Java 视频
录制 Python 视频