【设计模式】 抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析

    xiaoxiao2021-03-25  132

    前言

    在上文提到的最易懂的设计模式系列解析:工厂方法模式,发现工厂方法模式存在一个严重的问题:

    一个具体工厂只能创建一类产品

    而在实际过程中,一个工厂往往需要生产多类产品。为了解决上述的问题,我们又使用了一种新的设计模式:抽象工厂模式。

    在阅读下文前强烈建议先阅读  1. 1分钟全面了解“设计模式”  2. 最易懂的设计模式系列解析:简单工厂模式  3. 最易懂的设计模式系列解析:工厂方法模式  4. 其他设计模式介绍  1分钟全面了解“设计模式”  单例模式(Singleton) - 最易懂的设计模式解析  简单工厂模式(SimpleFactoryPattern)- 最易懂的设计模式解析  工厂方法模式(Factory Method)- 最易懂的设计模式解析  抽象工厂模式(Abstract Factory)- 最易懂的设计模式解析  策略模式(Strategy Pattern)- 最易懂的设计模式解析  适配器模式(Adapter Pattern)- 最易懂的设计模式解析  代理模式(Proxy Pattern)- 最易懂的设计模式解析  模板方法模式(Template Method) - 最易懂的设计模式解析  建造者模式(Builder Pattern)- 最易懂的设计模式解析  外观模式(Facade Pattern) - 最易懂的设计模式解析


    目录


    1. 介绍

    1.1 定义

    抽象工厂模式,即Abstract Factory Pattern,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。

    抽象工厂模式与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类

    1.2 主要作用

    允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。

    1.3 解决的问题

    每个工厂只能创建一类产品

    工厂方法模式的缺点


    2. 模式原理

    2.1 UML类图

    2.2 模式组成

    组成(角色) 关系 作用 抽象产品族(AbstractProduct) 抽象产品的父类 描述抽象产品的公共接口 抽象产品(Product) 具体产品的父类 描述具体产品的公共接口 具体产品(Concrete Product) 抽象产品的子类;工厂类创建的目标类 描述生产的具体产品 抽象工厂(Creator) 具体工厂的父类 描述具体工厂的公共接口 具体工厂(Concrete Creator) 抽象工厂的子类;被外界调用 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例

    如何理解抽象产品族、抽象产品和具体产品的区别呢?请看下图 

    2.3 使用步骤

    步骤1: 创建抽象工厂类,定义具体工厂的公共接口;  步骤2: 创建抽象产品族类 ,定义抽象产品的公共接口;  步骤3: 创建抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;  步骤4: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;  步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;  步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例


    3. 实例讲解

    接下来我用一个实例来对抽象工厂模式进行更深一步的介绍。

    3.1 实例概况

    背景:小成有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);随着客户需求的变化,A厂所在地的客户需要也模具类产品,B厂所在地的客户也需要容器类产品;冲突:没有资源(资金+租位)在当地分别开设多一家注塑分厂解决方案:在原有的两家塑料厂里增设生产需求的功能,即A厂能生产容器+模具产品;B厂间能生产模具+容器产品。  即抽象工厂模式

    3.2 使用步骤

    步骤1: 创建抽象工厂类,定义具体工厂的公共接口

    abstract class Factory{ public abstract Product ManufactureContainer(); public abstract Product ManufactureMould(); } 1234 1234

    步骤2: 创建抽象产品族类 ,定义具体产品的公共接口;

    abstract class AbstractProduct{ public abstract void Show(); } 123 123

    步骤3: 创建抽象产品类 ,定义具体产品的公共接口;

    //容器产品抽象类 abstract class ContainerProduct extends AbstractProduct{ @Override public abstract void Show(); } //模具产品抽象类 abstract class MouldProduct extends AbstractProduct{ @Override public abstract void Show(); } 123456789101112 123456789101112

    步骤4: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;

    //容器产品A类 class ContainerProductA extends ContainerProduct{ @Override public void Show() { System.out.println("生产出了容器产品A"); } } //容器产品B类 class ContainerProductB extends ContainerProduct{ @Override public void Show() { System.out.println("生产出了容器产品B"); } } //模具产品A类 class MouldProductA extends MouldProduct{ @Override public void Show() { System.out.println("生产出了模具产品A"); } } //模具产品B类 class MouldProductB extends MouldProduct{ @Override public void Show() { System.out.println("生产出了模具产品B"); } } 123456789101112131415161718192021222324252627282930313233 123456789101112131415161718192021222324252627282930313233

    步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;

    //A厂 - 生产模具+容器产品 class FactoryA extends Factory{ @Override public Product ManufactureContainer() { return new ContainerProductA(); } @Override public Product ManufactureMould() { return new MouldProductA(); } } //B厂 - 生产模具+容器产品 class FactoryB extends Factory{ @Override public Product ManufactureContainer() { return new ContainerProductB(); } @Override public Product ManufactureMould() { return new MouldProductB(); } } 123456789101112131415161718192021222324252627 123456789101112131415161718192021222324252627

    步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例

    //生产工作流程 public class AbstractFactoryPattern { public static void main(String[] args){ FactoryA mFactoryA = new FactoryA(); FactoryB mFactoryB = new FactoryB(); //A厂当地客户需要容器产品A mFactoryA.ManufactureContainer().Show(); //A厂当地客户需要模具产品A mFactoryA.ManufactureMould().Show(); //B厂当地客户需要容器产品B mFactoryB.ManufactureContainer().Show(); //B厂当地客户需要模具产品B mFactoryB.ManufactureMould().Show(); } } 123456789101112131415161718 123456789101112131415161718 结果: 生产出了容器产品A 生产出了容器产品B 生产出了模具产品A 生产出了模具产品B 1234 1234

    4. 优点

    降低耦合  抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;

    更符合开-闭原则  新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可

    简单工厂模式需要修改工厂类的判断逻辑

    符合单一职责原则  每个具体工厂类只负责创建对应的产品

    简单工厂中的工厂类存在复杂的switch逻辑判断

    不使用静态工厂方法,可以形成基于继承的等级结构。

    简单工厂模式的工厂类使用静态工厂方法


    5. 缺点

    抽象工厂模式很难支持新种类产品的变化。  这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

    对于新的产品族符合开-闭原则;对于新的产品种类不符合开-闭原则,这一特性称为开-闭原则的倾斜性。


    6. 应用场景

    在了解了优缺点后,我总结了工厂方法模式的应用场景:

    一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。这个系统有多个系列产品,而系统中只消费其中某一系列产品系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
    转载请注明原文地址: https://ju.6miu.com/read-7536.html

    最新回复(0)