抽象工厂模式( Abstract Factory)
- 抽象工厂模式是所有形态的工厂模式中最抽象和最具一般性的一种形态。
抽象工厂可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。可以把抽象工厂模式的用意分为三段。
1)一个系统需要消费多个抽象产品角色,这些抽象产品角色可以用Java接口或者抽象Java类实现。但是接口和抽象类是不能实例化的,所以如何满足创建产品的需求呢?
2)根据里氏代换原则,任何接收父类型的地方都可以接收子类型。
3)抽象工厂提供多个具体工厂角色,每一个具体工厂角色仅负责某一个具体产品角色的实例化。每一个具体工厂类负责创建抽闲该产品的某个具体子类的实例。
“抽象”来自“抽象产品角色”,而“抽象工厂”就是抽象产品角色的工厂。)]“抽象”来自“抽象产品角色”,而“抽象工厂”就是抽象产品角色的工厂。 - 多个产品等级结构
抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。 - 新引入的概念–产品族
所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。如下图,箭头所指就是三个工厂相关联的产品,他们位于三个不同的等级结构中的相同位置上,组成一个产品族。
每一个产品族中含有产品的数目与产品等级结构的数目是相等的。产品的等级结构和产品族将产品按照不同方向划分,形成一个二维的坐标系。如下图:
一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。
每一个产品族都有一个具体工厂,每一个具体工厂负责创建属于同一个产品族但是分属于不同等级结构的产品。 - 抽象工厂模式角色
1)抽象工厂角色:这个角色是工厂方法模式的核心,它与应用系统的商业逻辑无关。通常为Java接口或者抽象Java类。
2)具体工厂类角色:这个角色直接在客户端的调用下创建产品的实例。含有合适产品对象的逻辑,而这个逻辑是与应用系统的逻辑紧密相关的,通常为具体Java类。
3)抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类或它们共同拥有的接口。通常使用Java接口或者抽象Java类。
4)具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体Java类实现这个角色。
-
抽象工厂模式的使用场景
1)一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
2)这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品: (上面这一条叫做抽象工厂模式的原始用意。)
3)同属于同一个产品族的产品是在一起使用的, 这- -约束必须在系统的设计中体现出来
4)系统提供-个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。 -
抽象工厂模式在农场例子中的应用
可以看出,这个系统的产品可以分成两个等级结构: Fruit 和Veggie, 以及两个产品族: Tropical 和Northern。坐标图上出现了四个坐标点,分别代表TropicalFruit (热带水果)、TropicalVeggie ( 热带蔬菜)、NorthermFruit (北方水果)以及NorthemnVeggie ( 北方蔬菜)等四个产品。显然可以使用一一个工厂 族来封装它们的创建过程。这个工厂族的等级结构应当与产品族的等级结构完全平行。
-
抽象工厂模式与开闭原则
1)新增产品族:只需加入新的具体工厂类就可以了,没有必要修改已有的工厂角色或者产品角色,所以新增产品族是支持开闭原则的。
2)新增产品等级结构:在产品族数目不变的情况下新增产品等级结构,就需要修改所有的工厂角色,给每一个工厂类都增加一个新的工厂方法,而这显然是违背开闭原则的。