在学习 抽象工厂模式时,我们先需要了解两个概念:
产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海 尔电冰箱构成了一个产品族。
当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可以使用抽象工厂模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。抽象工厂模式示意图如图所示:
适用场景:
(1) 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是很重要的,用户无须关心对象的创建过程,将对象的创建和使用解耦。
(2) 系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。
(3) 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品可以是没有任何关系的对象,但是它们都具有一些共同的约束,如同一操作系统下的按钮和文本框,按钮与文本框之间没有直接关系,但它们都是属于某一操作系统的,此时具有一个共同的约束条件:操作系统的类型。
(4) 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。
练习:Sunny软件公司欲推出一款新的手机游戏软件,该软件能够支持Symbian、Android和Windows Mobile等多个智能手机操作系统平台,针对不同的手机操作系统,该游戏软件提供了不同的游戏操作控制(OperationController)类和游戏界面控制(InterfaceController)类,并提供相应的工厂类来封装这些类的初始化过程。软件要求具有较好的扩展性以支持新的操作系统平台,为了满足上述需求,试采用抽象工厂模式对其进行设计。
各个类和接口的结构:
各个类和接口代码:
//系统工厂接口:抽象工厂
public interface Factory {
InterfaceController createInterfaceController();
OperationController createOperationController();
}
//Android系统工厂:具体工厂
public class AndroidFactory implements Factory {
@Override
public InterfaceController createInterfaceController() {
return new AndroidInterfaceController();
}
@Override
public OperationController createOperationController() {
return new AndroidOperationController();
}
}
//Symbian系统工厂:具体工厂
public class SymbianFactory implements Factory{
@Override
public InterfaceController createInterfaceController() {
return new SymbianInterfaceController();
}
@Override
public OperationController createOperationController() {
return new SymbianOperationController();
}
}
//WinMobile系统工厂:具体工厂
public class WinMobileFactory implements Factory{
@Override
public InterfaceController createInterfaceController() {
return new WinMobileInterfaceController();
}
@Override
public OperationController createOperationController() {
return new WinMobileOperationController();
}
}
//游戏操作控制接口:抽象产品
public interface OperationController {
void display();
}
//游戏界面控制接口:抽象产品
public interface InterfaceController {
void display();
}
public class AndroidInterfaceController implements InterfaceController {
@Override
public void display() {
System.out.println("Android界面");
}
}
public class AndroidOperationController implements OperationController {
@Override
public void display() {
System.out.println("Android操作");
}
}
public class SymbianInterfaceController implements InterfaceController {
@Override
public void display() {
System.out.println("Symbian界面");
}
}
public class SymbianOperationController implements OperationController {
@Override
public void display() {
System.out.println("Symbian操作");
}
}
public class WinMobileInterfaceController implements InterfaceController {
@Override
public void display() {
System.out.println("WinMobile界面");
}
}
public class WinMobileOperationController implements OperationController {
@Override
public void display() {
System.out.println("WinMobile操作");
}
}
测试代码:
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
String factoryName = "com.[你的包具体路径].SymbianFactory";
Factory factory = null;
try {
factory = (Factory) Class.forName(factoryName).newInstance();
factory.createInterfaceController().display();
factory.createOperationController().display();
} catch (Exception e) {
logger.warn("获取类{}失败,信息:{}",factoryName,e.toString());
}
}
}
执行结果:
将String factoryName = "com.[你的包具体路径].*Factory";更换为AndroidFactory和WinMobileFactory,将得到