一、定义
抽象工厂模式(Abstract Factory Pattern)是一种比较常用的模式,其定义如下:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.即为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们 的具体类。
抽象工厂模式其本质是对工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
二、类图

三、四个重要角色
1.抽象工厂
工厂接口角色是所创建的具体产品工厂类的父类或接口,负责描述所有实例对象的共同接口或抽象类。规定了工厂对象的共同方法,是公具体工厂的公共接口。提供一个创建一系列产品对象的接口,不需要显式指定产品的具体类
2.具体工厂
抽象工厂接口角色的子类,用来被外界调用,描述具体的工厂
3.抽象产品
抽象产品角色是所创建的具体产品类的父类或接口,负责描述所有实例对象的共同接口或抽象类。规定了产品对象的共同方法。
4.具体产品
实现了抽象产品类或接口,定义了具体产品的特定行为和属性,所有创建的对象都充当这个角色的某个具体类的实例。
四、实际案例
1.定义两种不同形状的节能灯
/**
* U型形状的节能灯
*/
public interface UShapeLight {
public void energyUShapeLightProduct();
}
/**
* 螺旋形状的节能灯
*/
public interface SpiralShapeLight {
public void energySpiralShapeLightProduct();
}
2.实现两种形状不同灯光颜色的产品
/**
* U型形状白色光的节能灯
*/
public class UShapeWhiteLight implements UShapeLight {
@Override
public void energyUShapeLightProduct() {
System.out.println("U型白色灯光节能灯!");
}
}
/**
* U型形状红色光的节能灯
*/
public class UShapeRedLight implements UShapeLight{
@Override
public void energyUShapeLightProduct() {
System.out.println("U型红色灯光节能灯!");
}
}
public class SpiralShapeWhiteLight implements SpiralShapeLight{
@Override
public void energySpiralShapeLightProduct() {
System.out.println("螺旋形状的白色光节能灯!");
}
}
public class SpiralShapeRedLight implements SpiralShapeLight{
@Override
public void energySpiralShapeLightProduct() {
System.out.println("螺旋形状的红色光的节能灯!");
}
}
3.定义节能灯工厂
/**
* 节能灯产品工厂
*/
public interface AbstractLightFactory{
//U型节能灯
UShapeLight energyUShapeLightProduct();
//螺旋节能灯
SpiralShapeLight energySpiralShapeLightProduct();
}
4.实现两种不同灯光颜色的产品工厂
/**
* 白色灯光类节能灯工厂
*/
public class WhiteLightFactory implements AbstractLightFactory{
@Override
public UShapeLight energyUShapeLightProduct() {
//U型白色色灯光
return new UShapeWhiteLight();
}
@Override
public SpiralShapeLight energySpiralShapeLightProduct() {
//螺旋白色色灯光
return new SpiralShapeWhiteLight();
}
}
/**
* 红色灯光类节能灯工厂
*/
public class RedLightFactory implements AbstractLightFactory{
@Override
public UShapeLight energyUShapeLightProduct() {
//U型红色灯光
return new UShapeRedLight();
}
@Override
public SpiralShapeLight energySpiralShapeLightProduct() {
//螺旋红色灯光
return new SpiralShapeRedLight();
}
}
5.发起节能灯生产订单
public class FactoryProduce{
public static void main(String[] args) {
//客户A想要红色灯光的U型和螺旋形状的节能灯
LightFactory lightFactory = new RedLightFactory();
UShapeLight uShapeLight = lightFactory.energyUShapeLightProduct();
uShapeLight.energySavingLightProduct();
SpiralShapeLight spiralShapeLight = lightFactory.energySpiralShapeLightProduct();
spiralShapeLight.energySavingLightProduct();
System.out.println("-------------------------------------------------------------");
//客户B想要白色灯光的U型和螺旋形状的节能灯
lightFactory = new WhiteLightFactory();
uShapeLight = lightFactory.energyUShapeLightProduct();
uShapeLight.energySavingLightProduct();
spiralShapeLight = lightFactory.energySpiralShapeLightProduct();
spiralShapeLight.energySavingLightProduct();
}
}
6.执行结果
U型红色灯光节能灯!
螺旋形状的红色光的节能灯!
-------------------------------------------------------------
U型白色灯光节能灯!
螺旋形状的白色光节能灯!
7.扩展
此时,如果客户C需要同时订购形状和颜色混合的节能灯,那么只需要新建一个工厂类来实现抽象工厂接口变可实现不同要求的节能灯的生产,而不需要去修改已有的其他类,实现如下:
/**
* 混合类型的节能灯工厂
*/
public class MixShapeAndColourFactory implements AbstractLightFactory{
@Override
public UShapeLight energyUShapeLightProduct() {
//生产U型红色灯光的节能灯
return new UShapeRedLight();
}
@Override
public SpiralShapeLight energySpiralShapeLightProduct() {
//生产螺旋结构的白色灯光的节能灯
return new SpiralShapeWhiteLight();
}
}
public class FactoryProduce {
public static void main(String[] args) {
//客户C想要螺旋形状的白色灯光和U型红色灯光的节能灯
MixShapeAndColourFactory mixFactory = new MixShapeAndColourFactory();
SpiralShapeLight shapeLight = mixFactory.energySpiralShapeLightProduct();
shapeLight.energySpiralShapeProduct();
UShapeLight uShapeLight = mixFactory.energyUShapeLightProduct();
uShapeLight1.energyUShapeLightProduct();
}
}
执行结果如下:
螺旋形状的白色光节能灯!
U型红色灯光节能灯!
五、适用场景
1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
2.系统中有多于一个的产品族,而每次只使用其中某一产品族
3.属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
六、工厂方法模式的优缺点
1.优点
1.抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易
2.所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
3.当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
4.增加新的具体工厂和产品族方便,无须修改已有系统,符合“开闭原则”。
2.缺点
1.在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
2.开闭原则的倾斜性