1 基础知识
1.1 标准定义
抽象工厂模式标准定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1.2 分析和说明
抽象工厂模式是一个创建性的模式。与工厂方法模式一样,它要求工厂类和产品类分开。但是核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。一个具体的工厂类负责创建产品族中的各个产品。其实质就是由1个工厂类层次、N个产品类层次和N×M个产品组成。
图1 抽象工厂结构
Abstract Factory结构如图1所示。抽象工厂模式包括四个角色:抽象工厂角色;具体工厂类角色;抽象产品角色和具体产品角色。分别描述如下。
抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用接口或者抽象类实现,而所有的具体工厂类必须实现这个接口或继承这个抽象类。
具体工厂类(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。实际应用中使用具体类来实现这个角色。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用接口或者抽象类来实现这一角色。
具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。实际应用中使用具体类来实现这个角色。
2 应用场景举例
比如几家公司同时能生产计算机和电话。但是计算机系列包括PC机、笔记本电脑和服务器。电话系列包括座机电话和手机。对于这种情况就可以采用抽象工厂模式。其业务用例图见图3。
图2 抽象工厂模式的用例图
在这里可以把Company理解为抽象工厂(Abstract Factory)角色。CompanyA和CompanyB是具体工厂(Concrete Creator)角色。Computer和Telephone是两类不同的抽象产品(Product)角色。NotebookComputer和PersonalComputer是基于Computer抽象产品的具体产品(Concrete Product)角色。DesktopPhone和Mobile是基于Telephone抽象产品的具体产品(Concrete Product)角色。其实现类图如图3所示。
图3 抽象工厂模式的类图
抽象工厂模式实现的顺序图如图4所示,其实现步骤描述:
①创建一个Company1对象;
②调用Company1对象buildProduct方法,实际上从Company1对象创建一个Computer产品,为PersonalComputer对象。
③对PersonalComputer对象采取doUse方法;
④⑤与②③步骤一样,不过产生的是NotebookComputer对象。
⑥调用Company1对象buildProduct方法,实际上从Company1对象创建一个Telephone产品,为DesktopPhone对象。
⑦对DesktopPhone对象采取doUse方法;
⑧⑨与⑥⑦步骤一样,不过产生的是Mobile对象。
图4 抽象工厂模式实现顺序图
3.Java的实现程序代码
Java程序实现主要包括Company接口文件,Computer抽象类文件,Telephone抽象类文件,CompanyA类文件,CompanyB类文件,Mobile类文件、DesktopPhone类文件、NotebookComputer类文件和PersonalComputer类文件等9个文件。其关系如图3所示。下面分别列出这9个文件的程序代码,最后列出测试代码并显示输出结果。
Company属于抽象工厂(Abstract Factory)角色,Company的接口程序代码清单01所示。
程序代码清单01 public interface Company { public Computer bulidComputer(String Parameter); public Telephone bulidTelephone(String Parameter); } |
Computer抽象类和Telephone抽象类属于抽象产品(Abstract Product)角色,Computer和Telephone抽象类程序代码清单02所示。
程序代码清单02
public abstract class Computer { public void doUse(){} } public abstract class Telephone { public void doUse(){} } |
CompanyA类和CompanyB类属于具体工厂类(Concrete Factory)角色,CompanyA类和CompanyB类程序代码清单03所示。
程序代码清单03
public class CompanyA implements Company{ public Computer bulidComputer(String Parameter){ if (Parameter.equals("个人电脑")) { return new PersonalComputer(); } else if (Parameter.equals("笔记本电脑")) { return new NotebookComputer(); } else { return null; } } public Telephone bulidTelephone(String Parameter){ if (Parameter.equals("座机电话")) { return new DesktopPhone(); } else if (Parameter.equals("手机")) { return new Mobile(); } else { return null; } } } public class CompanyB implements Company{ public Computer bulidComputer(String Parameter){ if (Parameter.equals("个人电脑")) { return new PersonalComputer(); } else if (Parameter.equals("笔记本电脑")) { return new NotebookComputer(); } else { return null; } } public Telephone bulidTelephone(String Parameter){ if (Parameter.equals("座机")) { return new DesktopPhone(); } else if (Parameter.equals("手机")) { return new Mobile(); } else { return null; } } } |
Mobile类和DesktopPhone类属于具体产品(Concrete Product)角色,Mobile类和DesktopPhone类程序代码清单04所示。
程序代码清单04
public class Mobile extends Telephone { public void doUse() { System.out.println("这是手机的功能"); } } public class DesktopPhone extends Telephone { public void doUse() { System.out.println("这是座机电话的功能"); } } |
NotebookComputer类和PersonalComputer类属于具体产品(Concrete Product)角色,NotebookComputer类和PersonalComputer类程序代码清单05所示。
程序代码清单05
public class NotebookComputer extends Computer { public void doUse() { System.out.println("这是笔记本电脑的功能"); } } public class PersonalComputer extends Computer { public void doUse() { System.out.println("这是个人计算机的功能"); } } |
抽象工厂模式测试程序的代码清单06如下:
程序代码清单06
public class Client { public static void main(String[] args) { Company company1 = new CompanyA(); Computer computer1 = company1.bulidComputer("个人电脑"); computer1.doUse(); Computer computer2 = company1.bulidComputer("笔记本电脑"); computer2.doUse(); Telephone telephone1 = company1.bulidTelephone("座机电话"); telephone1.doUse(); Telephone telephone2 = company1.bulidTelephone("手机"); telephone2.doUse(); } } |
抽象工厂模式测试类输出结果如下所示:
这是个人计算机的功能 这是笔记本电脑的功能 这是座机电话的功能 这是手机的功能 |
4 扩展和说明
抽象工厂模式也是应用比较广泛的设计模式。对于抽象工厂模式,从两个层次上进行扩展。
一种是从抽象工厂中继承出来的具体工厂。即上述场景中的CompanyA,CompanyB,可以根据情况在增加CompanyC、CompanyD等。
一种是对产品进行扩充。可以增加一个产品类族,如计算机、手机、再增加电视机等。还有一种是增加具体的产品。如计算机下面还可以增加服务器等。
参考链接
5种创建型模式:
Gof23种设计模式(1)——工厂模式(Factory Method)
Gof23种设计模式(2)——抽象工厂模式(Abstract Factory)
Gof23种设计模式(3)——建造模式(Builder)
Gof23种设计模式(4)——原型模式(Prototype)
Gof23种设计模式(5)——单例模式(Singleton)
Gof23种设计模式 —— 创建型模式总结和比较
回到总目录:Gof23种设计模式(全解析)
(转载自微信公众号:架构设计模式)