设计模式第三篇 工厂模式(2) 抽象工厂模式 abstract factory

抽象工厂模式是工厂方法模式的进一步推广。抽象工厂模式可以处理具有相同或者相似的等级结构却又具有多个产品族特性的产品的创建,使客户端消费产品和产品的创建责任分离开来。

(1)什么是等级结构和产品族?

打个比方,现在有两种抽象产品角色,水果和蔬菜,我们就可以将水果和蔬菜看作成是相同的等级结构,水果又包括热带水果与亚热带水果,(蔬菜同理),那么我们这个时候就可以抽象出两个”族“出来:热带与亚热带,因此我们可以说热带水果属于水果这种等级结构,又具有热带族的属性

(2)抽象工厂相关结构

设计模式第三篇 工厂模式(2) 抽象工厂模式 abstract factory

图释:上图代表具有相同等级结构(如productA1与ProductA2)的产品又具有不同产品族的特性,如ProductA1属于族1,ProductA2属于族2,可以根据颜色辨别,ProductA2与ProductB2属于同一个族,将上述产品所在结构以及族特性可以抽象为下面的相图。

设计模式第三篇 工厂模式(2) 抽象工厂模式 abstract factory

设计模式第三篇 工厂模式(2) 抽象工厂模式 abstract factory

上图代表抽象工厂与具体产品工厂的结构图

创建产品的工作原理如下:

设计模式第三篇 工厂模式(2) 抽象工厂模式 abstract factory

解释:

抽象工厂:Creator ,抽象工厂模式的核心, 不负责创建具体的产品,只需要提供创建抽象产品角色(亦可以理解为产品等级结构)的方法。方法接口的个数应该参照等级结构的个数

具体工厂:ConcreteCreator 1 和ConcreteCreator 2,具有创建相关具体产品的逻辑判断,负责具体产品的创建

抽象产品:ProductA与ProductB,代表产品的等级结构

具体产品:ProductA1、ProductA2...

需要多少具体工厂,可以根据有多少产品族而定

下面我们继续以水果\蔬菜为例,现有一个农场,种植了蔬菜和水果,蔬菜又分为北方蔬菜和男方蔬菜,苹果同理,现在客户需要得到男方水果。具体看一下抽象工厂模式的实现:

/** * 抽象工厂 * 只提供得到水果和蔬菜的方法接口 * @author zhang_jin1 */ public interface Factory { public Fruit getFruit(); public Vegetables getVegetables(); }


/** * 具体工厂类 * @author zhang_jin1 * */ public class NorthFactory implements Factory { @Override public Fruit getFruit() { return new NorthFruit(); } @Override public Vegetables getVegetables() { return new NorthVegetables(); } }

/** * 具体工厂类 * @author zhang_jin1 * */ public class SouthFactory implements Factory { @Override public Fruit getFruit() { return new SouthFruit(); } @Override public Vegetables getVegetables() { return new SouthVegetables(); } }


/** * 北方水果类 * @author zhang_jin1 * */ public class NorthFruit implements Fruit { public NorthFruit() { System.out.println("NorthFruit is created..."); } }


/** * 北方蔬菜类 * @author zhang_jin1 * */ public class NorthVegetables implements Vegetables { public NorthVegetables() { System.out.println("NorthVegetables is created..."); } }


/** * 南方水果类 * @author zhang_jin1 * */ public class SouthFruit implements Fruit { public SouthFruit(){ System.out.println("SouthFruit is create..."); } }


/** * 南方蔬菜类 * @author zhang_jin1 * */ public class SouthVegetables implements Vegetables { public SouthVegetables(){ System.out.println("SouthVegetables is created..."); } }

/** * 客户类 * @author zhang_jin1 * */ public class Client { public static void main(String[] args) { //业务:客户需要的是南方水果 Factory f = new SouthFactory(); Fruit fruit = f.getFruit(); } }


抽象工厂模式的优缺点:

(1) 对于产品等级结构不变的情况下,改变产品族时:

不需要修改原有代码,只需要新增或者删除相应的具体工厂即可

(2)对于产品族数目不变的情况下,改变产品等级机构时:

因为抽象工厂的方法接口是根据产品等级机构而来,所以增加或者删除某产品等级结构就需要修改抽象工厂,所以需要修改源代码!