简介
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
不同点
为了更清晰地理解抽象工厂模式,需要先引入两个概念:
产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是CPU,其子类有intelcpu、amdcpu,则抽象cpu与具体品牌的cpu之间构成了一个产品等级结构,抽象cpu是父类,而具体品牌的cpu是其子类。
产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如intel工厂生产的intelcpu、intel主板,intelcpu位于cpu产品等级结构中,intel主板位于主板产品等级结构中。
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。
类图
源码
cpu
public interface CPU {public void calculate(); }
intelcpu
public class IntelCPU implements CPU {private Integer pins;//cpu脚针数public IntelCPU(Integer pins) {this.pins = pins;}public void calculate() {System.out.println("Intel CPU 脚针数:" + pins);} }
amdcpu
public class AMDCPU implements CPU {private Integer pins;//cpu脚针数public AMDCPU(Integer pins) {this.pins = pins;}public void calculate() {System.out.println("AMD CPU 脚针数:" + pins);} }
主板
public interface MainBoard {public void installCPU(); }
intel主板
public class IntelMainBoard implements MainBoard {private Integer pins;public IntelMainBoard(Integer pins) {this.pins = pins;}public void installCPU() {System.out.println("Intel MainBoard 针脚数:"+pins);} }
amd主板
public class AMDMainBoard implements MainBoard {private Integer pins;public AMDMainBoard(Integer pins) {this.pins = pins;}public void installCPU() {System.out.println("AMD MainBoard 针脚数:" + pins);} }
工厂
public interface AbstractFactory {public CPU buyCPU();public MainBoard buyMainBoard();}
intel工厂
public class IntelFactory implements AbstractFactory {public CPU buyCPU() {return new IntelCPU(555);}public MainBoard buyMainBoard() {return new IntelMainBoard(555);} }
amd工厂
public class AMDFactory implements AbstractFactory {public CPU buyCPU() {return new IntelCPU(666);}public MainBoard buyMainBoard() {return new IntelMainBoard(666);} }
商家
public class Store {private CPU cpu = null;private MainBoard mainBoard = null;//组装pcpublic void setupPC(AbstractFactory factory) {this.cpu = factory.buyCPU();//买cputhis.mainBoard = factory.buyMainBoard();//买主板//买内存 机箱...this.cpu.calculate();this.mainBoard.installCPU();} }
测试
public static void main(String[] args) {Store store = new Store();AbstractFactory intelModel = new IntelFactory();store.setupPC(intelModel);//intel型号的电脑 /* Intel CPU 脚针数:555Intel MainBoard 针脚数:555*/}
适用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
- 这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
- 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。(比如:Intel主板必须使用Intel CPU、Intel
芯片组)
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
优点
- 分离接口和实现:客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
- 使切换和添加产品族变得容易:因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。我也可以再添加一个新的装机方案,一个新的产品族,都是很方便的。
缺点
不容易扩展新的产品等级,比如我要加一个硬盘、内存什么的。那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
Head First 设计模式(中文版)的示例:
码云地址:https://gitee.com/manusas/FactoryDP
我只是大自然的搬运工(thx):
hxxp://blog.csdn.net/zhshulin/article/details/38349211
hxxp://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/abstract_factory.html