前言
抽象工厂模式比工厂方法模式的抽象程度更高。在工厂方法模式中每一个具体工厂只需要生成一种具体的产品,但是在抽象工厂模式中每一个具体工厂只可以生产一组相关的具体产品,这样的一组产品称为产品族,产品族中的每一个产品都分属于某一个产品继承等级结构。
一、产品等级结构与产品族
产品等级结构:产品灯具结构即产品的继承结构,例如一个抽象类时电视机,其子类包括海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的位于不同产品等级结构中的一组产品,例如海尔电器工厂生产的海尔电视机、海尔冰箱,海尔电视机位于电视机产品等级结构中,海尔冰箱位于冰箱产品的等级结构中,海尔电视机、海尔冰箱构成了一个产品族。
二、抽象工厂模式概述
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。与工厂方法模式相比,抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品。
三、抽象工厂模式结构与实现
结构
抽象工厂模式包含以下4个角色:
- AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
- ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
- AbstractProduct(抽象产品):它为每中产品声明接口,在抽象产品中声明了产品所具有的业务方法。
- ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
实现
抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以时接口,也可以时抽象类或者具体类。其典型代码如下:
public interface AbstractFactory(){
public AbstractProductA createProductA();
public AbstractProductB createProductB();
具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族。对于每一个具体工厂类,其典型代码如下
public class ConcreteFactory1 extends AbstractFactory(){
//工厂方法一
public AbstractProudctA createProductA(){
return new ConcreteProductA1();
}
public class ConcreteFactory1 extends AbstractFactory(){
//工厂方法一
public AbstractProudctB createProductB(){
return new ConcreteProductB1();
}
}
抽象工厂模式应用实例
实例说明
则结构图
在上图中,SkinFactory接口充当抽象工厂,其子类SpringSkinFactory和SummerSkinFactory充当具体工厂,接口Button、TextField和ComboBox充当抽象产品,其子类SpringButton、SpringTextField、SpringComboBox和SummerButton、SummerTextField、SummerComboBox充当具体产品。
抽象工厂模式的缺点
例如上面例子,如果在设计之初因为考虑不全面,忘记为某种类型的界面组件(比如一个单选按钮RadioButton)提供不同皮肤下的风格化显示,那么在往系统中增加单选按钮时将发现非常麻烦,无法在满足开闭原则的前提下增加单选按钮,原因是抽象工厂SkinFactory中根本没有提供创建单选按钮的方法,如果需要增加单选按钮,首先需要修改抽象工厂接口SkinFactory,在其中新增声明创建单选按钮的方法,然后逐个修改具体工厂类,增加相应方法以实现在不同的皮肤库中创建单选按钮此外还需要修改客户端,否则单选按钮无法应用于现有系统。即抽象工厂模式如果要增加新的产品等级结构十分麻烦。