Java 设计模式之抽象工厂模式

设计模式系列

创建型设计模式

Java 设计模式之单例模式

Java 设计模式之静态工厂方法模式

Java 设计模式之工厂方法模式

Java 设计模式之抽象工厂模式

Java 设计模式之Builder模式

Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别

结构型设计模式

Java 设计模式之代理模式

Java 设计模式之外观模式

文章目录

    • 设计模式系列
      • 创建型设计模式
      • 结构型设计模式
    • 前言
    • 定义
    • 示例
      • 场景
      • UML类图
      • 程序代码
    • 总结
    • 感谢

前言

前两讲中我们分别学习了 静态工厂方法模式工厂方法模式 ,比较简单,在开发中的应用范围也比较广泛,建议大家多看源码,多多实践。

本讲要关注的 抽象工厂模式 ,与上一讲的 工厂方法模式 同样隶属于 GOF 提出的 23 种设计模式。抽象工厂模式难度上也不见得高,咱们结合示例来讨论,会更加易于理解。只是应用范围不广,大家作为扩展知识即可,技能的掌握还是以前两讲的为必要。

定义

很官方:为创建 一组相关或者相互依赖的对象 提供一个接口,而不需要指定他们的具体类。

啥意思?

拆开来说:

1、咱们之前的工厂都是只关注一个产品,本讲的工厂呢要关注的是 有相关性的几个产品、或者某产品中的不同组成

2、但是工厂接口(或抽象类)不生产具体的 那几个产品、或者某产品中的那几个不同组成 ,只声明他们的抽象,具体的生产交给工厂接口(或抽象类)的子类完成。

来吧,结合示例,一触即通。

示例


场景

1、月饼 = 皮 + 馅,月饼的类型不同,其皮和馅的细节会有差别,不过无论如何逃不出皮和馅的范畴。

2、月饼工厂生产月饼,实际上就是生产皮和馅,只不过五仁月饼工厂生产的是五仁的皮和馅,豆沙月饼工厂声场的是豆沙的皮和馅。

下面来看下 UML 类图。

UML类图

Java 设计模式之抽象工厂模式_第1张图片

图 1    抽象工厂模式的 UML 类图


程序代码

定义了一个月饼皮接口 IWrapper ,其中声明了一个制作月饼皮的方法 make() ,分别有五仁月饼皮的产品类 FivekernelWrapper 和豆沙月饼皮的产品类 BeansandWrapper 实现此接口。


程序清单 1     月饼皮接口 IWrapper
public interface IWrapper {
    /**
     * 制作月饼皮
     */
    void make();
}

程序清单 2     五仁月饼皮的产品类 FivekernelWrapper
public class FivekernelWrapper implements IWrapper {

    @Override
    public void make() {
        System.out.println("制作五仁月饼皮");
    }
    
}

程序清单 3     豆沙月饼皮的产品类 BeansandWrapper
public class BeansandWrapper implements IWrapper {

    @Override
    public void make() {
        System.out.println("制作豆沙月饼皮");
    }
    
}

月饼馅的相关接口及实现类与月饼皮的一致,不再赘述。

定义了一个月饼工厂抽象类 MooncakesFactory ,其中声明了生产月饼皮产品接口和生产月饼馅产品接口的抽象方法,分别有五仁月饼工厂和豆沙月饼工厂类继承此抽象类并实现抽象方法。


程序清单 4     月饼工厂抽象类 MooncakesFactory
public abstract class MooncakesFactory {
    /**
     * 生产月饼皮的产品接口
     * 
     * @return IWrapper
     */
    abstract IWrapper makeWrapper();

    /**
     * 生产月饼馅的产品接口
     * 
     * @return IFilling
     */
    abstract IFilling makeFilling();
}

程序清单 5     五仁月饼工厂类 FivekernelFactory
public class FivekernelFactory extends MooncakesFactory {

    @Override
    IWrapper makeWrapper() {
        return new FivekernelWrapper();
    }

    @Override
    IFilling makeFilling() {
        return new FivekernelFilling();
    }
    
}

程序清单 6     豆沙月饼工厂类 BeansandFactory
public class BeansandFactory extends MooncakesFactory {

    @Override
    IWrapper makeWrapper() {
        return new BeansandWrapper();
    }

    @Override
    IFilling makeFilling() {
        return new BeansandFilling();
    }
    
}

再看一下调用方代码:
程序清单 7     生产月饼皮和月饼馅
public class Main {
    public static void main(String[] args) {
        // 五仁月饼
        MooncakesFactory fivekernelFactory = new FivekernelFactory();
        fivekernelFactory.makeWrapper().make();
        fivekernelFactory.makeFilling().make();

        // 豆沙月饼
        MooncakesFactory beansandFactory = new BeansandFactory();
        beansandFactory.makeWrapper().make();
        beansandFactory.makeFilling().make();
    }
}

结果示例,如图 2:
Java 设计模式之抽象工厂模式_第2张图片

图 2    结果示例


总结

至此,本讲对抽象工厂模式的介绍基本就结束了。大家结合 UML 类图和示例代码看的话,这种模式也比较容易理解。

这种模式的缺点是当需要扩展产品时,需要新增的类的数量会快速提高。比如说上述场景中需要增加鲜肉月饼,至少需要增加 MeatFactoryMeatWrapperMeatFilling 三个类,类的数量的增长率有 30% 之多。

这种模式的应用场景比较少,大家要从源码里找的话,可以结合《Android 源码设计模式解析与实战》看一下 Android 底层对 MediaPlayer 的处理。

另外,Android 常见功能 主题切换 很适合应用此设计模式。

本讲的示例源码已经放在 Gihub 上:AbstractFactoryPattern

感谢

  • 《Android源码设计模式解析与实战》 何红辉 关爱民
  • 在线绘图网站 ProcessOn

你可能感兴趣的:(架构设计)