1、定义
抽象工厂模式(Abstract Factory Pattern):为创建一组相关或相互依赖的对象提供一个接口,并且无需指定它们的具体类。
2、形式
抽象工厂模式通用类图如下所示:
从类图上来看该模式跟工厂模式似乎没有差别,但抽象工厂模式实际上是工厂模式的升级版。在存在多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
抽象工厂一般都定义了多个工厂类去管理同一类业务对象,精化后的类图如下:
对应的通用源码为:
AbstractProductA
public abstract class AbstractProductA {
//每个产品共有的方法
public void shareMethod(){}
//每个产品相同方法的不同实现
public abstract void doSomething();
}
ProductA1
public class ProductA1 extends AbstractProductA{
public void doSomething() {
System.out.println("产品A1的方法实现");
}
}
ProductA2
public class ProductA2 extends AbstractProductA{
public void doSomething() {
System.out.println("产品A2的方法实现");
}
}
AbstractProductB
public abstract class AbstractProductB {
//每个产品共有的方法
public void shareMethod(){}
//每个产品相同方法的不同实现
public abstract void doSomething();
}
ProductB1
public class ProductB1 extends AbstractProductB{
public void doSomething() {
System.out.println("产品B1的方法实现");
}
}
ProductB2
public class ProductB2 extends AbstractProductB{
public void doSomething() {
System.out.println("产品B2的方法实现");
}
}
AbstractCreator
public abstract class AbstractCreator {
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
Creator1
public class Creator1 extends AbstractCreator{
public AbstractProductA createProductA() {
return new ProductA1();
}
public AbstractProductB createProductB() {
return new ProductB1();
}
}
Creator2
public class Creator2 extends AbstractCreator{
public AbstractProductA createProductA() {
return new ProductA2();
}
public AbstractProductB createProductB() {
return new ProductB2();
}
}
Client
public class Client {
public static void main(String[] args) {
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
AbstractProductA a1 = creator1.createProductA();
AbstractProductA a2 = creator2.createProductA();
AbstractProductB b1 = creator1.createProductB();
AbstractProductB b2 = creator2.createProductB();
/*
*其他业务代码
* */
}
}
上面的场景类中,没有调用任何实现类,只需要知道某一个产品的工厂方法就可以直接产生一个产品对象,因此实现了高低层的解耦。
示例:一个具体的例子就是现实生活中的生产车间,比如生产螺丝和螺母,对应两个产品族,对每个产品族根据不同的型号(不同的型号的螺丝螺母)进行划分,也即把每种型号作为一个产品等级约束,那么就需要设置两个工厂来分别生产螺丝螺母。
对应到上述类图
AbstractProductA
对应抽象螺丝类;ProductA1
和ProductA2
分别对应两个不同型号的具体螺丝类;AbstractProductB
对应抽象螺母类;ProductB1
和ProductB2
分别对应两个不同型号的具体螺母类;AbstractCreator
对应抽象工厂,包含两个抽象方法,创建螺母和创建螺丝;CreatorA1
对应具体工厂类1,创建型号等级为1的螺丝和螺母CreatorA2
对应具体工厂类2,创建型号等级为2的螺丝和螺母
在抽象工厂模式中,产品族的数量对应抽象工厂类中的生产方法数量;产品等级数量对应具体工厂类数量。
从上述定义可以看出,抽象工厂模式同扩展的工厂方法模式(多工厂模式)的区别在于将抽象产品扩展到了抽象产品族。
3、优缺点
优点
- 封装性:每个产品的实现不用高层模块关心,上层模块只需要调用相应接口就可获得具体的产品对象
- 可以设定产品族内的约束且不用对外层公开,如果需要对产品族进行约束(例如每生产一个螺丝同时生产两个螺母),可以在工厂内实现。
缺点
- 产品族扩展非常困难:如果要增加一个产品,那么抽象工厂类要增加一个新的产品创建方法,并且两个实现类都要改(例如增加一个螺丝钳产品,那么
AbstractCreator
中要增加createProductC
方法,并且实现类也要修改),这严重违反了开闭原则。
注:对于产品等级的扩展,该模式是非常容易的,例如增加一个型号等级,只需要新增一个工厂类负责新增型号的产品生产即可,因此从这点上来看抽象工厂模式是复合开闭原则的。
4、使用场景
抽象工厂模式的使用场景定义非常简单:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。就按之前的例子来说,在不同地方下汽车会使用不同型号的螺丝和螺母,因此这些对象具有了共同的约束条件—产品型号,因此我们可以使用抽象工厂模式生成不同型号的产品应对不同的场景。
5、小结
抽象工厂模式是一个比较简单的设计模式,在软件开发过程中使用较多,只要是关于不同场景下的产品差异问题,都可以考虑使用抽象工厂模式。