参考源

    https://www.bilibili.com/video/BV1mc411h719?p=4&vd_source=299f4bc123b19e7d6f66fefd8f124a03

    https://www.bilibili.com/video/BV1u3411P7Na?spm_id_from=333.999.0.0&vd_source=299f4bc123b19e7d6f66fefd8f124a03


    抽象工厂模式(Abstract Factory Pattern)属于创建型模式

    抽象工厂模式是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。

    在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象。

    前面的工厂模式通过定义顶层抽象工厂类,通过继承的方式,针对于每一个产品都提供一个工厂类用于创建。

    不过这种模式只适用于简单对象,当需要生产许多个产品族的时候,这种模式就有点乏力了,比如:

    设计模式 03 抽象工厂模式 - 图1

    实际上这些产品都是成族出现的,比如小米的产品线上有小米手机、小米平板等,华为的产品线上也有华为手机、华为平板。

    如果按照之前的工厂模式来进行设计,那就需要单独设计 9 个工厂来生产上面这些产品,显然这样就比较浪费时间的。

    这时可以使用抽象工厂模式,将多个产品都放在一个工厂中进行生成,按不同的产品族进行划分。

    比如小米,那么就创建一个小米工厂,这个工厂里面可以生产整条产品线上的内容,包括小米手机、小米平板等。

    1、创建产品接口

    1. /**
    2. * 手机
    3. */
    4. public interface Phone {
    5. /**
    6. * 打电话
    7. */
    8. void call();
    9. }
    1. /**
    2. * 平板
    3. */
    4. public interface Pad {
    5. /**
    6. * 看视频
    7. */
    8. void video();
    9. }

    2、定义具体产品

    1. /**
    2. * 小米手机
    3. */
    4. public class XiaoMiPhone implements Phone {
    5. @Override
    6. public void call() {
    7. System.out.println("小米手机打电话");
    8. }
    9. }
    1. /**
    2. * 小米平板
    3. */
    4. public class XiaoMiPad implements Pad {
    5. @Override
    6. public void video() {
    7. System.out.println("小米平板看视频");
    8. }
    9. }
    1. /**
    2. * 华为手机
    3. */
    4. public class HuaWeiPhone implements Phone {
    5. @Override
    6. public void call() {
    7. System.out.println("华为手机打电话");
    8. }
    9. }
    1. /**
    2. * 华为平板
    3. */
    4. public class HuaWeiPad implements Pad {
    5. @Override
    6. public void video() {
    7. System.out.println("华为平板看视频");
    8. }
    9. }

    3、创建抽象工厂

    1. /**
    2. * 抽象工厂
    3. */
    4. public abstract class AbstractFactory {
    5. /**
    6. * 获取手机
    7. * @return 手机对象
    8. */
    9. public abstract Phone getPhone();
    10. /**
    11. * 获取平板
    12. * @return 平板对象
    13. */
    14. public abstract Pad getPad();
    15. }

    4、创建品牌工厂

    1. /**
    2. * 小米工厂
    3. */
    4. public class XiaoMiFactory extends AbstractFactory{
    5. @Override
    6. public Phone getPhone() {
    7. return new XiaoMiPhone();
    8. }
    9. @Override
    10. public Pad getPad() {
    11. return new XiaoMiPad();
    12. }
    13. }
    1. /**
    2. * 华为工厂
    3. */
    4. public class HuaWeiFactory extends AbstractFactory {
    5. @Override
    6. public Phone getPhone() {
    7. return new HuaWeiPhone();
    8. }
    9. @Override
    10. public Pad getPad() {
    11. return new HuaWeiPad();
    12. }
    13. }

    5、生产使用

    1. // 小米手机
    2. Phone xiaomiPhone = new XiaoMiFactory().getPhone();
    3. // 华为手机
    4. Phone huaweiPhone = new HuaWeiFactory().getPhone();
    5. // 小米平板
    6. Pad xiaoMiPad = new XiaoMiFactory().getPad();
    7. // 华为平板
    8. Pad huaweiPad = new HuaWeiFactory().getPad();
    9. // 输出测试
    10. xiaomiPhone.call();
    11. huaweiPhone.call();
    12. xiaoMiPad.video();
    13. huaweiPad.video();

    输出结果为:

    1. 小米手机打电话
    2. 华为手机打电话
    3. 小米平板看视频
    4. 华为平板看视频

    如此即实现了各工厂生产不同产品族的产品并实现对应的功能。

    一个工厂可以生产同一个产品族的所有产品,这样按族进行分类,显然比之前的工厂模式更好。

    不过,缺点还是有的,如果产品族新增了产品,那么我就不得不去为每一个产品族的工厂都去添加新产品的生产方法,违背了开闭原则。

    且这种模式需要使用的类远多于工厂模式,除非是类似这种产品族的业务场景,否则还是更推荐工厂模式实现。