文章目录
一、工厂方法模式简介
二、工厂方法模式适用场景
三、工厂方法模式优缺点
四、工厂方法模式代码示例
1、产品抽象类
2、产品实现类 1
3、产品实现类 2
4、抽象工厂类
5、实现工厂类 1
6、实现工厂类 2
7、测试类
五、扩展上述工厂方法模式
1、扩展的产品实现类
2、扩展的工厂实现类
3、测试类
一、工厂方法模式简介
工厂方法模式 : 定义一个 创建对象 的 接口 , 让 实现这个接口的子类 决定 实例化哪个类 , 工厂方法让 类的实例化 推迟到子类中进行 ;
工厂方法模式类型 : 创建型 ;
创建 实例对象 过程可能会很复杂 , 有可能会 导致大量的重复代码 , 工厂方法模式 通过 定义 一个单独的 创建 实例对象 的方法 , 解决上述问题 ;
通过 子类 实现 这个方法 , 创建具体的 实例对象 ;
二、工厂方法模式适用场景
工厂方法模式适用场景 :
重复代码 : 创建对象 需要使用 大量重复的代码 ;
不关心创建过程 : 客户端 不依赖 产品类 , 不关心 实例 如何被创建 , 实现等细节 ;
创建对象 : 一个类 通过其 子类 来 指定 创建哪个对象 ;
客户端 不需要知道 具体 产品类 的 类名 , 只需要知道 所对应的工厂 即可 , 具体的产品对象 , 由对应的工厂创建 , 客户端只需要知道 产品 对应的 工厂 ;
工厂方法模式 利用了 面向对象 的 多态性 , 和 里式替换 原则 ;
子类对象 覆盖 父类对象 , 使 系统 更容易扩展 , 将 创建对象的过程 推迟到子类实现 , 创建对象的任务 , 委托给 多个 工厂子类 中的某一个 , 客户端不需要关心是哪个 工厂子类 创建的 产品对象 ;
工厂子类 一般都是 需要的时候 , 动态指定 ;
三、工厂方法模式优缺点
工厂方法模式优点 :
不关心创建细节 : 用户 只需要 关心 所需产品 对应的工厂 , 无需关心创建细节 ;
符合开闭原则 : 加入 新产品 , 符合开闭原则 , 提高可扩展性 ;
工厂方法模式 中 , 使用 工厂类创建 产品对象 , 同时 隐藏了 具体的 产品类 被 实例化 的细节 ;
工厂方法模式缺点 :
增加复杂性 : 类的个数容易过多 , 增加系统复杂度 ;
在 添加新产品 时 , 除了编写 新的产品类 之外 , 还要 编写该产品类对应的 工厂类 ;
增加难度 : 增加了系统 抽象性 和 理解难度 ;
工厂方法本身 利用了抽象 , 该模式中会 引入抽象层 , 如果要动态创建产品类 , 还要 引入反射技术 ;
设计模式 的 使用 , 要根据 实际的 业务场景 , 模型 综合平衡考量 , 不能过分遵守设计原则 和 设计模式 ;
四、工厂方法模式代码示例
1、产品抽象类
package factorymethod; /** * 视频抽象 */ public abstract class Vedio { /** * 生产视频 */ public abstract void produce(); }
2、产品实现类 1
package factorymethod; public class JavaVedio extends Vedio { @Override public void produce() { System.out.println("录制 Java 视频"); } }
3、产品实现类 2
package factorymethod; public class PythonVedio extends Vedio { @Override public void produce() { System.out.println("录制 Python 视频"); } }
4、抽象工厂类
注意看注释 :
package factorymethod; /** * 工厂类抽象 * 具体的创建 产品对象 的工厂类 , 继承该抽象类 * 客户端实际创建对象时 , 调用的是工厂类子类实现 * * 该类中只有 1 个抽象方法 , 也可以使用接口进行定义 工厂类 抽象 * 但在实际的业务场景中 , 工厂类的某些属性 或 某些行为是已知的 * 需要提前定义出来 , 接口就无法完成该定义 * 因此 , 一般情况下 工厂抽象 使用 抽象类进行定义 , 不使用接口 * * 产品等级 : 相同类型的产品 , 称为产品等级 * 对于生产 Vedio 都是同一个产品等级 * Java 视频 和 Python 视频 的产品等级一致 , 都是视频 * 二者 的 等级 都在 视频这个等级上 * * 产品族 : 与 产品等级 相对应的概念是 产品族 * 这是区分 工厂方法模式 和 抽象工厂模式 的重要概念 * 如果每个视频有配套的解说 , 那么 视频 与 解说 是同一个产品族 * * 工厂方法模式 用于解决 同一个产品等级 的业务抽象问题 * * 具体产生 什么类型的视频 * 由 VedioFactory 的子类 JavaVedioFactory / PythonVedioFactory 决定 * 不是由 VedioFactory 决定 * VedioFactory 只规定 规范 契约 * 不规定产生哪个类型的视频 * * 扩展 : * 如果要扩展一个新类型的视频 , 如 Kotlin 视频 * 只需要新增加一个 Vedio 子类 和 一个 VedioFactory 子类 即可 */ public abstract class VedioFactory { /** * 创建 Vedio 实例对象的方法由 子类 实现 * @return */ public abstract Vedio getVedio(); }