本文介绍了GoF中的工厂模式。
模式推演
创造不同类型的披萨:
初始写法为:
1 | class PizzaStore{ |
显然,如果要加入一种新的pizza,就得修改这个方法,并且下方的prepare这些方法是不变的。我们必须封装变化。
创建简单工厂:
从需求来看,创建pizza是变化部分,我们将其从原来的类中独立出来,用一个专门的类来负责创造:
1 | class SimpleFactrory{ |
简单工厂其实不是一种设计模式,而像是一种编程习惯。
工厂方法
每个地方的pizza口味不一样,例如深圳和广州两地的,用简单工厂方法,不能满足这种扩展需求,因此我们进一步优化,把createPizza方法通过抽象类的方式,让子类来决定:
1 | class abstract PizzaStore{ |
工厂方法与简单工厂的不同是:简单工厂把全部事情,在一个地方都处理了,而工厂方法是创建一个框架,让子类决定如何实现。简单工厂不涉及到继承,只是一个简单的类,而工厂方法可以利用继承具备弹性。
依赖倒置
如果没有使用工厂方法,写法是这样的:
1 | class PizzaStore{ |
依赖关系如下:
如果设计一个Pizza的基类,PizzaStore只依赖于Pizza类,那么依赖关系如下:
可见,依赖关系从上往下,变成从下往上了,即底层的组件反向依赖高层的抽象。
OO原则(依赖倒置原则):要依赖抽象,不要依赖具体类。
当工厂创造的产品种类不止一种且可能重复时
Pizza需要一些原料,例如sauce、cheese、clam,这些原料对于多种Pizza可能相同,所以我们需要通过工厂来生成这些原料,但也可能不同,所以我们需要定义多个工厂,把工厂的共有方法通过抽象提取出来:
1 | public interface PizzaIngredientFactroy{ |
这种设计模式,就是抽象工厂模式,抽象工厂与工厂方法不同,工厂方法是通过继承的方式,只创造一种产品,而抽象工厂是通过组合,创造一个产品家族。
定义
工厂方法模式(Factory Pattern):定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到子类。
类图:
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
类图: