适用场合
动态实现
与一系列实现了同一接口、可以被同等对待的类打交道时,需要使用工厂模式
节省设置开销
如果对象需要进行复杂并且彼此相关的设置,那么使用工厂模式可以减少每种对象所需要的代码量。它可以在实例化所需要的对象之前先一次性的进行设置。
如果所用的类要求加载外部库的话,工厂方法可以对这这些库进行检查并动态加载那些未找到的库
用许多小对象组成一个大对象
工厂方法可以用来创建封装了许多小对象的对象。如果你不想让某个子系统与比较大的那个对象之间形成强耦合,而是想在运行时从许多子系统中进行挑选的话,那么使用工厂方法是比较理想的选择。
简单工厂
假设你想开几个自行车商店,每个店都有几种型号的自行车出售。这可以用一个类来表示
1 | // BicycleFactory 单体 |
BicycleFactory 就是简单工厂的一个例子。这种模式把成员对象的创建工作转交给一个外部对象。这个外部对象可以像本例是一个简单的命名空间,也可以是一个类的实例。
工厂模式
真正的工厂模式与简单工厂模式的区别在于,它不是另外使用一个类或对象来创建自行车,而是使用一个子类。
按照正式定义,工厂是一个将其成员对象的实例化推迟到子类中进行的类。
1 | // BicycleShop class (抽象类) |
一个栗子 (XHR 工厂)
- 简单工厂
1 | // AjaxHandler 接口 |
- 专用型连接对象
这个栗子可以进一步扩展,把工厂模式用在两个地方,以便根据网络条件创建专门的请求对象。
QueueHandler 会在发起新的请求之前先确保所有的请求都已经成功处理,而 OfflineHandler 则会在用户处于离线状态时把请求缓存起来。
1 | // QueueHandler class 在发起新的请求之前先确保所有请求已经成功处理 |
- 在运行时选择连接对象(工厂模式)
因为程序员根本不可能知道各个最终用户实际面临的网络条件,所以不可能要求他们在开发中选择使用那个处理器类,而是应该用一个工厂在运行时选择最合适的类
1 | // XhrManager 单例 |
总结
简单工厂通常另外使用一个类或者对象封装实例化操作,而真正的工厂模式则需要实现一个抽象的工厂方法并把实例化工作推迟到子类中进行。
工厂模式可以弱化对象间的耦合,防止代码重复。