我所理解的设计模式系列·第2.3篇·三种工厂模式傻傻分不清楚(3)抽象工厂模式

2022/01/20 设计模式 共 2297 字,约 7 分钟

本文主要介绍抽象工厂模式(Abstract Factory Pattern),它的定义是:“提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。”。

design-patttern-2

1. 模式介绍

工厂模式(Factory Design Pattern)是一种极为常用的用于创建对象的设计模式,在绝大部份开源框架中都有最佳实践,最为人所知的大概就是 Spring 的 BeanFactory 了。

工厂模式属于创建型模式,事实上它有三种不同的实现方式:简单工厂模式、工厂方法模式、抽象工厂模式

本文主要介绍抽象工厂模式(Abstract Factory Pattern),它的定义是:“提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。”

抽象工厂模式是工厂方法模式的升级版,在抽象工厂模式中,抽象工厂接口有若干个方法需要具体工厂类实现。换言之,抽象工厂模式中的工厂类可以创建多个对象,同时这多个对象没有继承、实现接口的关系。

2. 应用场景

抽象工厂模式适用的场景是:一类对象,或者是一类没有具体关系的对象,如果拥有着相同的约束,那么就可以使用抽象工厂模式。

本段话摘自《设计模式之禅》(第2版)9.3.3 抽象工厂模式的使用场景

3. 类图

抽象工厂方法模式中有四种角色:

  • 抽象产品(IProduct):描述了工厂创建的所有对象的抽象接口
  • 具体产品(Concrete Product):工厂创建的具体实例,实现了抽象产品接口
  • 抽象工厂(Abstract Factory):描述了工厂创建具体产品的方法,任何用来创建具体产品的工厂类必须实现该接口
  • 具体工厂(Concrete Factory):创建具体产品的具体工厂类,实现了抽象工厂,描述了创建某个指定类型的具体产品的过程

design-patttern-2

这四种角色与工厂方法模式是一样的,但是抽象工厂模式与工厂方法模式的区别就在于:抽象工厂模式中,一个工厂可以创建多种类型的对象,而工厂方法模式中,一个工厂只能创建一种类型的对象。

4. 实现方式

下面基于一个简单的场景来展示抽象工厂模式的实现方式。

引用介绍工厂方法模式中的那个示例场景,目前已经有 IPhone、Huawei 两大手机品牌以及用来创建这两种手机品牌的手机工厂: IPhoneFactory 和 HuaweiFactory 。

假设现在又多加了一个需要创建耳机的需求,先来定义耳机接口,它有一个播放音乐的方法:

public interface HeadSet {
    void playMusic();
}

然后创建 IPhone 和 HuaWei 对象分别对应的耳机配件—— AirPods 和 FreeBuds,实现 HeadSet 耳机接口。

public class AirPods implements HeadSet {
    @Override
    public void playMusic() {
        System.out.println("AirPods...好像还挺好用?");
    }
}

public class FreeBuds implements HeadSet {
    @Override
    public void playMusic() {
        System.out.println("华为蓝牙耳机...好像丑一点?");
    }
}

随后定义新的抽象工厂,它有两个方法,一个是用来创建手机,一个是用来创建耳机。

public interface NewPhoneFactory {

    /**
     * 获得手机对象的接口方法
     * @return Phone
     */
    Phone getPhone();

    /**
     * 获得耳机的接口方法
     * @return
     */
    HeadSet getHeadSet();
}

IPhone 和 Huawei 的具体工厂类也就比较清晰了,如下所示:

public class NewIPhoneFactory implements NewPhoneFactory {
    @Override
    public Phone getPhone() {
        return new IPhone();
    }

    @Override
    public HeadSet getHeadSet() {
        return new AirPods();
    }
}

public class NewHuaWeiFactory implements NewPhoneFactory {
    @Override
    public Phone getPhone() {
        return new HuaWei();
    }

    @Override
    public HeadSet getHeadSet() {
        return new FreeBuds();
    }
}

最后,我们编写一些代码来测试抽象工厂。

public static void main(String[] args) {
    NewIPhoneFactory iPhoneFactory = new NewIPhoneFactory();
    // 获得手机对象
    Phone iPhone = iPhoneFactory.getPhone();
    iPhone.takePhotos();
    // 获得耳机对象
    HeadSet airPods = iPhoneFactory.getHeadSet();
    airPods.playMusic();
}

// 输出
// IPhone...魔鬼前置
// AirPods...好像还挺好用?

5. 优缺点

最后,照例来说说抽象工厂模式的优缺点。

抽象工厂模式的优点:

  • 具体工厂类可以创建一个产品家族中的多个类型对象
  • 有良好的封装性,将客户端与创建具体产品的逻辑解耦

抽象工厂模式的缺点:

  • 拓展性较差,违反开闭原则。若上述的示例中又新增一个创建充电器的方法,所有抽象工厂都需要新增这个方法。

6. 小结

本文描述了抽象工厂模式的定义、应用场景、类图、实现方式以及优缺点。

7. 参考资料

  • 《设计模式之禅》(第2版)

最后,本文收录于个人语雀知识库: 我所理解的后端技术,欢迎来访。

文档信息

Search

    Table of Contents