第4章 工厂方法(Factory Method)模式
第3章讲述了如何创建单例对象,本章将讲述如何使用工厂方法模式创建普通对象。
模式是我们在OOP编程中反复看到的模式之一,本章主要内容包括:
介绍工厂方法模式。
如何为每个线程创建独立的拷贝。
静态工厂方法的使用。
4.1 工厂方法模式
工厂方法模式是我们常用的模式之一,我们经常在以下情景使用。
客户类不关心使用哪个具体类,只关心该接口所提供的功能。
创建过程比较复杂,例如需要初始化其他关联的资源类,读取配置文件等。
接口有很多具体实现或者抽象类有很多具体子类时,你可能需要为客户代码写一大串if-else逻辑来决定运行时使用哪个具体实现或者具体子类。
不希望给客户程序暴露过多此类的内部结构,隐藏这些细节可以降低耦合度。
优化性能,比如缓存大对象或者初始化比较耗时的对象。
GoF为工厂方法模式给出的定义如下。
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
为创建对象定义一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟至子类。
工厂方法模式是对实例化过程进行封装而形成的,客户对象无须关心实例化这些类的细节,把它们交给工厂类,在GoF的定义中,为工厂类定义了一个工厂接口。该模式比较简单,我们从UML静态类图着手。
我们有一个Product接口,其实现类为ConcreteProduct,工厂负责创建Product对象,这样客户对象就不用关心使用哪个实例以及如何初始化该实例,以后Product实现类如果发生了改变,也不会引起客户代码的改动,只要维护相应的工厂类即可。此模型中,Factory接口是工厂接口,其实现类是ConcreteFactory,如图4-1所示。
图4-1
代码实现
根据上述的UML图示,不难写出实现代码,如下所示。
代码注解
Factory接口定义了createProduct()方法来返回Product类型的实例对象,ConcreteFactory类实现了该方法,每次调用都会实例化一个新的ConcreteProduct对象返回。
工厂方法模式使用起来也非常简单,代码如下所示。
如果具体实现类较多,我们可以定义一个参数化的工厂方法,根据不同的输入返回不同的实现子类,代码片段如下。
客户对象可以根据需要传入不同的参数获得不同类型的对象。