在设计模式—工厂方法模式中提到,该模式中一个工厂只能生产一个产品。。但是在现实生活中,一个工厂往往可以生产多类产品。于是有了抽象工厂模式。
抽象工厂模式(Abstract Factory Pattern),其定义如下:
:::info Provide an interface for creating families of related or dependent objectswithout specifying their concrete classes.
为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类. :::
也就是说,抽象工厂中每个工厂可以创建多种类的产品,而工厂方法每个工厂只能创建一类产品。
其组成模型如下:
| 组成 | 关系 | 作用 |
|---|---|---|
| 抽象产品族(Abstract Product) | 抽象产品的父类 | 定义抽象产品的公共接口 |
| 抽象产品(Product) | 具体产品的父类 | 提供描述产品的公共接口 |
| 具体产品(Concrete Product) | 具体产品类,工厂生产的目标类 | 抽象产品具体化 |
| 抽象工厂(Factory) | 具体工厂的父类 | 描述具体工厂的公共接口 |
| 具体工厂(Concrete Factory) | 抽象工厂的子类;被外界调用 | 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例 |
何谓产品族,抽象产品和具体产品。例如:手机就是一个抽象产品组,不同的公司手机对应为抽象产品,例如苹果,小米,华为等,对于抽象产品华为来说,Mate 30,Mate 40等不同机型称之为具体产品。
抽象工厂模式的优点
- 降低耦合度。抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;
- 符合开闭原则;新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可;
- 符合单一职责原则;每个具体工厂类只负责创建对应的产品;
抽象工厂模式的缺点
- 抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了开闭原则。
对于新的产品族符合开闭原则;对于新的产品种类不符合开闭原则。
抽象工厂模式最佳实践
- 有多个系列产品,而系统中只消费其中某一系列产品;
- 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现
抽象工厂模式实现步骤
- 创建抽象产品族,定义每一产品族的公共接口;
- 创建抽象产品,定义产品的公共能力;
- 创建具体产品类,实现自己的独有能力;
- 创建抽象工厂,定义生产的公共能力;
- 创建具体工厂类,实现自己的生成能力,具体到能生产哪种产品;
- 外界调用具体工厂生成具体产品。
抽象工厂模式使用示例
某代工厂既代工生产海尔冰箱和空调,也代工生产格力冰箱和空调。
- 抽象产品族为代工电器,IElectricAppliance类来表示,因为这两者都属于电器,都有一个公共能力,即工作(work);
- 冰箱抽象为一个类;空调抽象为一个类;
- 设计两个工厂,一个专门生产海尔的产品,一个专门生产格力的产品
public class AbstractFactory {/*** 抽象产品族类,并定义具体产品的基本功能*/public interface IElectricAppliance {void work();}/*** 冰箱抽象产品类,并定义具体产品的基本功能*/public interface IRefrigerator extends IElectricAppliance {}/*** 冰箱抽象产品类,并定义具体产品的基本功能*/public interface IAirConditioner extends IElectricAppliance {}/*** 具体产品类:海尔冰箱*/public static class HaierRefrigerator implements IRefrigerator {@Overridepublic void work() {System.out.println("海尔冰箱开始工作");}}/*** 具体产品类:格力冰箱*/public static class GreeRefrigerator implements IRefrigerator {@Overridepublic void work() {System.out.println("格力冰箱开始工作");}}/*** 具体产品类:海尔空调*/public static class HaierAirConditioner implements IAirConditioner {@Overridepublic void work() {System.out.println("海尔空调开始工作");}}/*** 具体产品类:格力空调*/public static class GreeAirConditioner implements IAirConditioner {@Overridepublic void work() {System.out.println("格力空调开始工作");}}/*** 工厂抽象,提供生产产品的方法*/public interface IFactory {IRefrigerator createRefrigerator();IAirConditioner createAirConditioner();}/*** 海尔类工厂:生产海尔冰箱和海尔空调*/public static class HaierFactory implements IFactory {@Overridepublic IRefrigerator createRefrigerator() {return new HaierRefrigerator();}@Overridepublic IAirConditioner createAirConditioner() {return new HaierAirConditioner();}}/*** 铅笔类工厂*/public static class GreeFactory implements IFactory {@Overridepublic IRefrigerator createRefrigerator() {return new GreeRefrigerator();}@Overridepublic IAirConditioner createAirConditioner() {return new GreeAirConditioner();}}public static void main(String[] args) {// 生产海尔冰箱new HaierFactory().createRefrigerator().work();// 生产海尔空调new HaierFactory().createAirConditioner().work();// 生产格力冰箱new GreeFactory().createRefrigerator().work();// 生产格力空调new GreeFactory().createAirConditioner().work();}}
运行结果如下:
:::success
海尔冰箱开始工作
海尔空调开始工作
格力冰箱开始工作
格力空调开始工作
:::
