抽象工厂模式
抽象工厂模式的用意
抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。
系统的设计
采用抽象工厂模式设计出的系统类图如下图所示:
从上图所示,抽象工厂涉及到以下角色:
- 抽象工厂(AbstractFactory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用 Java 接口或者抽象 Java 类实现,而所有的具体工厂类必须实现这个 Java 接口或继承这个抽象 Java 类。
- 具体工厂类(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。通常使用 Java 类实现这个角色。
- 抽象产品类(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用 Java 接口或者抽象 Java 类实现这一角色。
- 具体产品类(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体 Java 类实现这个角色。
下面利用相图描述,会看到在相图上出现两个等级结构 A 和 B,以及两个产品族 1 和 2,如下图所示:
源代码
抽象产品角色的源代码
public interface Creator {
/**
* 产品等级结构A的工厂方法
*/
public ProductA factoryA();
/**
* 产品等级结构B的工厂方法
*/
public ProductB factoryB();
}
具体工厂类 ConcreteCreator1 和 ConcreteCreator2 的源代码
public class ConcreteCreator1 implements Creator {
public ProductA factoryA() {
return new ProductA1();
}
public ProductB factoryB() {
return new ProductB1();
}
}
public class ConcreteCreator2 implements Creator {
public ProductA factoryA() {
return new ProductA2();
}
public ProductB factoryB() {
return new ProductB2();
}
}
一般而言,有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。每一个产品等级结构中有具体产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。
具体产品类 ProductA 的源代码
客户端需要的是产品,而不是工厂。在真实的系统中,产品类应当与应用系统的商业逻辑有密切关系。下面是产品等级结构 A 的抽象产品角色,在这个示意系统中,这个抽象产品角色是由一个 Java 接口实现的,如下代码所示:
public interface ProductA {
}
可以看出这个接口也只是一个标识接口,下面展示其具体的实现类
具体产品类 ProductA1 和 ProductA2 的源代码
public class ProductA1 implements Product {
public ProductA1() {
}
}
public class ProductA2 implements Product {
public ProductA2() {
}
}
而在这个演示系统中,产品等级结构B的源代码和A大致相同,略。
谈一谈优劣:
优点:
-
分离接口和实现:
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。 -
使得切换产品族变得容易:因为一个具体的工厂实现代表的是一个产品族,客户端选用不同的工厂实现,就相当是在切换不同的产品族。
缺点:
-
不太容易扩展新的产品:
如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这一就会导致所有的工厂实现类都需要修改 -
容易造成类层次复杂
来源《Java与模式》