工厂方法
工厂方法(Factory Method)也称虚构造器(Virtual Constructor)
意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
适用性
Use the Factory Method pattern when
- a class can’t anticipate the class of objects it must create.(一个类不知道它所需要的对象的类,也就是说,不需要知道具体产品的类名,只需要知道创建它的具体工厂就行了)
- a class wants its subclasses to specify the objects it creates.(一个类通过子类来指定所要创建的对象,抽象工厂类只提供创建产品的接口,由子类来确定要创建的具体的对象,充分利用多态的特性,运行时子类对象替换父类对象)
- classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.(将创建对象的任务委托给多个工厂子类中的一个,这样使用时就不用关心到底是哪一个工厂子类创建产品子类,需要的时候动态指定就可以了)
结构
工厂方法的结构如下图
Product
– 定义工厂方法所创建的对象所提供的接口(或者抽象类)。ConcreteProduct
– 实现Product的接口(或者抽象类)。Creator
– 声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteCreator对象。
– 可以调用工厂方法以创建一个Product对象。- ConcreteCreator
– 表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
– 重写(Override)工厂方法以返回一个ConcreteProduct实例。
工厂方法模式实现(Implement)
案例
现在用经典的shape,circle,square例子来说明工厂方法的实现。
首先定义一个Product,Shape类,Shape有自己的名字name,还有抽象方法draw()绘制图形,代码如下
现在有两个ConcreteProduct,分别是Circle类和Square类,代码如下
|
|
接下来我们定义一个Creator,ShapeFactory类,代码如下
要生成这两个产品,现在得将Creator生成产品的工作委托给它的子类ConcreteCreator去执行,定义CircleFactory类和SquareFactory类
|
|
最后,我们的Client来使用工厂方法创建我们需要的对象
得到的输出结果为
可以看到我们的Client并不需要知道要创造产品的细节甚至产品名,它们都是Shape类型,由工厂方法创建出来,但是在执行的时候会去执行子类中重写的draw方法。
总结
本文对工厂方法进行了简单的介绍,可以得出工厂方法有以下几个优点
- 良好的封装性,类之间的耦合性降低,调用者需要创建一个具体的产品的对象时,只需要去找到对应的工厂方法就可以了,不用去了解详细的对象初始化过程。调用者与产品类之间完全解耦,产品类的实现变化时,调用者都不关心,调用者只关心抽象类的接口,符合迪米特法则。
- 优秀的扩展性,符合开闭原则,需要增加产品类时,只需要在原有的基础上增加新实现的具体工厂类即可,不用去修改原有代码的实现。
- 利用多态特性,符合里氏替换原则,子类可以替换父类
- 符合依赖倒置原则,只依赖了产品的接口(或者抽象类)而不依赖具体的实现