Java设计模式(四)工厂方法模式
定义与类型
- 定义:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。
- 类型:创建型
适用场景
- 创建对象需要大量重复的代码
- 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
- 一个类通过其子类来指定创建哪个对象
优点
- 用户只需要关心所需产品对应的工厂,无须关心创建细节
- 加入新产品符合开闭原则,提高可扩展性
缺点
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
Coding
工厂方法模式从一定意义上讲是从简单工厂模式衍生过来的,创建产品抽象类
1 | public abstract class Video { |
创建具体产品
1 | public class JavaVideo extends Video { |
创建产品工厂方法抽象类
1 | public abstract class VideoFactory { |
创建产品工厂方法实现类(每个产品都有对应的实现类)
1 | public class JavaVideoFactory extends VideoFactory { |
测试类
1 | public class Test { |
控制台输出
1 | 录制Java课程 |
如果我们现在新增一个产品–前端课程,我们需要创建产品类,产品工厂类,但是无需改动其他代码,做到了对扩展开放,对修改关闭,符合开闭原则。
1 | public class FEVideo extends Video { |
但是,我们也不难看出工厂方法模式的缺点–类的个数容易过多,增加复杂度。
因为一旦我们需要现在产品,就需要创建产品对应的产品实现类,以及产品工厂方法类,无疑增加了类的个数和系统的复杂度。
完整的UML类图
源码解析
Collection
源码
jdk中典型的工厂方法模式体现为java.util.Collection
抽象产品为java.util.Iterator
1 | public interface Iterator<E> { |
抽象工厂定义了创建产品族的方法java.util.Collection.#iterator
1 | Iterator<E> iterator(); |
由子类来定义具体创建产品的逻辑,如java.util.ArrayList.#iterator
1 | public Iterator<E> iterator() { |
而具体的产品定义为java.util.ArrayList$Itr
1 | private class Itr implements Iterator<E> { |
UML类图
URLStreamHandlerFactory
源码
再来看一个典型例子,java.net.URLStreamHandlerFactory
作为工厂方法抽象类,定义了创建产品的抽象方法
1 | public interface URLStreamHandlerFactory { |
产品抽象类就是java.net.URLStreamHandler
1 | public abstract class URLStreamHandler { |
产品的工厂方法实现类为sun.misc.Launcher$Factory
1 | private static class Factory implements URLStreamHandlerFactory { |
可以发现,工厂实现类通过反射类创建具体的产品实现类,而产品实现类非常多
这样满足了开闭原则,也没有过多的增加类的数量,值得我们学习。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 观沧海!
评论