你真的了解抽象工厂模式吗?

本文详细介绍了抽象工厂模式,包括其定义、结构、角色和优缺点。抽象工厂模式提供了一种创建一系列相关对象的接口,使得创建过程与具体实现解耦。在产品等级结构中,它允许更换产品族而不影响客户端代码。然而,增加新的产品等级结构可能会导致工厂类的修改,违反了开闭原则。最佳实践表明,抽象工厂模式适用于需要创建多个产品等级结构的情况,例如在不同操作系统下创建相同功能但实现不同的编辑器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

        设计模式的本质在于抽象、解耦,用抽象来隔离变化。将复杂的事务按照六大设计原则,分解成一个个单一职责的个体。换而言之,是个体的高内聚和简单化,然后再组合到一起完成职能。合理使用设计模式,可以使程序设计更加标准化、代码编制更加工程化,使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

        上一篇文章中,我们已经聊完了GOF23中的第二个模式——工厂方法模式,如果没有看过的,可以回顾一下。

创建型模式的工作原理

创建型模式提供了一种创建对象的机制,抽象实例化的过程,隐藏了对象的创建细节,对外只提供一个通用接口,能够提升已有代码的灵活性和可复⽤性。创建型模式有五种:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。本文带着大家重新学习第三种设计模式——抽象工厂模式(Abstract Factory)。

抽象工厂模式

为了更清晰地理解抽象工厂模式,需要先引入两个概念:

        产品等级结构:产品等级结构即产品的继承结构,如一个手机抽象类,其子类有小米手机、华为手机、苹果手机,则抽象手机与具体品牌的手机之间形成了一个产品等级结构,抽象手机类是父类,而具体品牌的手机类是子类。

        产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如小米工厂生成的小米手机、小米电脑、小米音响组成一个产品族。这三种产品属于不同的产品等级结构,但由同一个工厂创建。

定义

        抽象工厂模式提供了一个创建一系列相关或相互依赖的对象接口,而且无须指定它们的具体类。抽象工厂模式是工厂方法模式的加强版,抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对一个产品等级结构,而抽象工厂模式面对多个产品等级结构,一个工厂角色可以负责多个不同产品等级结构中的产品对象的创建 。

结构

抽象工厂模式的通用类图如下:

抽象工厂模式包含如下角色:

1、AbstractFactory:抽象工厂角色

public abstract class AbstractFactory {

    /**
     * 创建A类产品
     *
     * @return
     */
    public abstract AbstractProductA createProductA();

    /**
     * 创建B类产品
     *
     * @return
     */
    public abstract AbstractProductB createProductB();
}

2、ConcreteFactory:具体工厂类

public class ConcreteFactory1 extends AbstractFactory {
    @Override
    public AbstractProductA createProductA() {
        //生产等级1的A产品
        return new ConcreteProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        //生产等级1的B产品
        return new ConcreteProductB1();
    }
}

ConcreteFactory2 的代码类似,不再赘述。

3、AbstractProduct:抽象产品类

public abstract class AbstractProductB {

    public void commonMethod() {
        //公共方法
    }

    //不同产品不同的业务方法
    public abstract void method();
}

AbstractProductB 的代码类似,不再赘述。

4、ConcreteProduct:具体产品类

public class ConcreteProductA1 extends AbstractProductA {

    @Override
    public void method() {
        System.out.println("实现产品A1的业务逻辑");
    }
}

public class ConcreteProductA2 extends AbstractProductA {

    @Override
    public void method() {
        System.out.println("实现产品A2的业务逻辑");
    }
}

ConcreteProductB1和ConcreteProductB2 的代码类似,不再赘述。

场景类

public static void main(String[] args) {
    AbstractFactory factory1 = new ConcreteFactory1();
    AbstractFactory factory2 = new ConcreteFactory2();
    AbstractProductA productA1 = factory1.createProductA();
    AbstractProductB productB1 = factory1.createProductB();
    AbstractProductA productA2 = factory2.createProductA();
    AbstractProductB productB2 = factory2.createProductB();

    productA1.method();
    productB1.method();
    productA2.method();
    productB2.method();
}

优点

1、封装性,调用方只需要知道具体工厂就可以创建多个不同产品等级结构中的产品,外部访问时隐藏了具体产品的创建过程。从而可以实现高内聚低耦合的设计目的。

2、产品族内的约束为非公开状态。比如制造一台小米手机需要三个摄像头,一台诺基亚手机需要两个摄像头,这样的生产过程对调用工厂类的模块来说是透明的,上层不需要知道这个约束,能获得一个产品对象就可以,具体的产品族内的约束是在工厂内实现。

缺点

抽象工厂模式的最大缺点就是产品族扩展非常困难,我们以通用代码为例,如果要增加一个产品C,也就是说产品等级结构由原来的2个增加到3个。此时,抽象类AbstractFactory要增加一个方法createProductC(),然后具体工厂实现类都要修改,这严重违反了开闭原则,会带来较大的不便。

最佳实践

        一个系统不依赖于产品类实例如何被创建、组合和依赖的细节,这对于所有类型的工厂模式都是重要的。

        抽象工厂模式所要解决的问题就是在⼀个产品族中,存在多个不同类型的产品情况下,接⼝选择的问题。比如说,有一个产品族中有图片编辑器和视频编辑器,在不同的操作系统下虽然有相同的界面及功能,但是底层代码实现可能是完全不同的,我们不可能设计多套不同的应用,应该通过抽象工厂模式屏蔽操作系统对应用的影响。

        抽象工厂模式在纵向扩展(增加产品等级结构)上,扩展比较困难。但是横向扩展(增加产品组)比较容易,只需要对应增加一个新的具体工厂即可,对已有代码无须做任何修改。

        抽象工厂模式的这种性质称为“开闭原则”的倾斜性,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,但不能为新的产品等级结构的增加提供这样的方便。

总结

        无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,结合通用代码与⾃⼰实际的业务,尝试结构改造,慢慢体会其中的感受,慢慢总结出属于自己的葵花宝典。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值