- 针对简单工厂模式,自己曾经还说过:这根本就不算一种设计模式,是高人对长久以来的编程习惯的总结
- 简单工厂模式中,调用者得知道自己想创建的对象的名称(传递给工厂的参数),工厂才能根据名称为其创建对应的对象
- 要想支持新类型的对象创建,需要修改已有的工厂类代码,严重违背了开闭原则
- 作为一个聪明的程序员,当老大说你的简单工厂模式代码违背了开闭原则时,你想出了一个新的实现方法
- 每种对象的创建对应一个工厂,而不是由一个工厂去完成多种对象的创建
- 当需要支持创建新类型的对象时,不需要修改已有的工厂类,只需要增加一个对应的工厂类即可
- 这样的实现,没有违背开闭原则了吧?
- 对简单工厂模式这样的升级改造,形成了一种新的设计模式 —— 工厂方法模式
- 其UML图如下:
- 抽象工厂:定义了创建产品的接口
- 具体工厂:实现了抽象工厂中的抽象方法,负责具体的创建
- 从UML图可以看出,相对简单工厂模式:
- 工厂方法模式需要定义一个抽象工厂
- 实现抽象工厂、创建多个具体工厂,每个工厂负责一种产品的生产
- 需求:
- 客户告诉你他需要支持不同格式的图片加载器,例如jpg、png、gif等
- 使用时,他想直接获取现成的加载器实例
- 他目前能想到上述三种图片格式,后续可能还需要支持更多图片格式
- 考虑到系统的可扩展性,工厂方法模式就可以派上用场了:为客户提供多个工厂类,可以生成不同的图片加载器实例
创建抽象产品:
-
Reader接口
public interface Reader { void read(); }
创建具体产品
-
实现Reader接口,创建各种格式的图片加载器类
public class JpgReader implements Reader { @Override public void read() { System.out.print("read jpg"); } } public class PngReader implements Reader { @Override public void read() { System.out.print("read png"); } } public class GifReader implements Reader { @Override public void read() { System.out.print("read gif"); } }
创建抽象工厂:
-
抽象工厂里面有一个生成加载器实例的方法
-
看了看好多JDK源码,通过工厂类获取对象实例时,基本都是getXXX,而非createXXX
-
例如,ManagementFactory中的各种getXXXMXBean()方法,都是在获取对应MXBean的实例
-
因此,这里也使用get开头命名方法
public interface ReaderFactory { Reader getReader(); }
创建具体工厂
- 针对每种格式的Reader创建对应的具体工厂类
public class JpgReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new JpgReader(); } } public class PngReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new PngReader(); } } public class GifReaderFactory implements ReaderFactory { @Override public Reader getReader() { return new GifReader(); } }
客户端使用工厂类
- 客户端使用的代码如下:
ReaderFactory factory = new JpgReaderFactory(); // 获取工厂实例 Reader reader = factory.getReader(); // 通过工厂创建图片加载器实例 reader.read(); // 输出:read jpg
优点
- 对调用者来说:屏蔽了对象的创建过程,只需要知道对应的工厂名称,就能获得现成的对象
- 对开发人员来说:需要支持更多类型的对象创建时,无需修改现有的工厂类,只需要增加一个对应的工厂类即可
缺点
- 工厂类个数容易过多:每种类型的对象的创建都需要一个对应的工厂类
- 抽象不够:
- 每个工厂只能创建一种类型的对象,有时需要一个工厂能创建多种类型的对象。
- 这些对象是相关的或相互依赖的,由一个工厂来创建最合适不过了
- 工厂方法模式是对简单工厂模式的进一步抽象,可以在不修改已有代码的情况下引入新的产品(新类型的对象),满足了开闭原则
- 会导致工厂类过多,也无法在创建一组相关或相互依赖的对象场景下使用 —— 使用抽象工厂模式解决
题外话
- 说实话,到现在为止,自己都没有发现工厂模式有还什么高深之处
- 自己简单搜索了一下JDK源码,好像也没有看到具体的应用
- 最多是ManagementFactory,一个创建各种MXBean的工厂
- 它不是单纯的简单工厂模式或者工厂方法模式,而是每种MXBean的创建都是一个单独的get方法
- 最多可以说,是对简单工厂模式if-else语句的拆分
- 或者是对工厂方法模式的一个改进:减少具体工厂类,只需要一个工厂;工厂中,不同的get方法实现不同对象的创建
参考链接:这是两篇不同的博客,名字相似而已
- 工厂模式——这一篇真够了
- 工厂模式——看这一篇就够了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)