设计模式系列
创建型设计模式
Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别
结构型设计模式
前言
前两讲中我们分别学习了 静态工厂方法模式 和 工厂方法模式 ,比较简单,在开发中的应用范围也比较广泛,建议大家多看源码,多多实践。
本讲要关注的 抽象工厂模式 ,与上一讲的 工厂方法模式 同样隶属于 GOF 提出的 23 种设计模式。抽象工厂模式难度上也不见得高,咱们结合示例来讨论,会更加易于理解。只是应用范围不广,大家作为扩展知识即可,技能的掌握还是以前两讲的为必要。
定义
很官方:为创建 一组相关或者相互依赖的对象 提供一个接口,而不需要指定他们的具体类。
啥意思?
拆开来说:
1、咱们之前的工厂都是只关注一个产品,本讲的工厂呢要关注的是 有相关性的几个产品、或者某产品中的不同组成 ;
2、但是工厂接口(或抽象类)不生产具体的 那几个产品、或者某产品中的那几个不同组成 ,只声明他们的抽象,具体的生产交给工厂接口(或抽象类)的子类完成。
来吧,结合示例,一触即通。
示例
场景
1、月饼 = 皮 + 馅,月饼的类型不同,其皮和馅的细节会有差别,不过无论如何逃不出皮和馅的范畴。
2、月饼工厂生产月饼,实际上就是生产皮和馅,只不过五仁月饼工厂生产的是五仁的皮和馅,豆沙月饼工厂声场的是豆沙的皮和馅。
下面来看下 UML 类图。
UML类图
程序代码
定义了一个月饼皮接口 IWrapper ,其中声明了一个制作月饼皮的方法 make()
,分别有五仁月饼皮的产品类 FivekernelWrapper 和豆沙月饼皮的产品类 BeansandWrapper 实现此接口。
public interface IWrapper {
/**
* 制作月饼皮
*/
void make();
}
public class FivekernelWrapper implements IWrapper {
@Override
public void make() {
System.out.println("制作五仁月饼皮");
}
}
public class BeansandWrapper implements IWrapper {
@Override
public void make() {
System.out.println("制作豆沙月饼皮");
}
}
月饼馅的相关接口及实现类与月饼皮的一致,不再赘述。
定义了一个月饼工厂抽象类 MooncakesFactory ,其中声明了生产月饼皮产品接口和生产月饼馅产品接口的抽象方法,分别有五仁月饼工厂和豆沙月饼工厂类继承此抽象类并实现抽象方法。
public abstract class MooncakesFactory {
/**
* 生产月饼皮的产品接口
*
* @return IWrapper
*/
abstract IWrapper makeWrapper();
/**
* 生产月饼馅的产品接口
*
* @return IFilling
*/
abstract IFilling makeFilling();
}
public class FivekernelFactory extends MooncakesFactory {
@Override
IWrapper makeWrapper() {
return new FivekernelWrapper();
}
@Override
IFilling makeFilling() {
return new FivekernelFilling();
}
}
public class BeansandFactory extends MooncakesFactory {
@Override
IWrapper makeWrapper() {
return new BeansandWrapper();
}
@Override
IFilling makeFilling() {
return new BeansandFilling();
}
}
再看一下调用方代码:
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:
总结
至此,本讲对抽象工厂模式的介绍基本就结束了。大家结合 UML 类图和示例代码看的话,这种模式也比较容易理解。
这种模式的缺点是当需要扩展产品时,需要新增的类的数量会快速提高。比如说上述场景中需要增加鲜肉月饼,至少需要增加 MeatFactory 、MeatWrapper 、MeatFilling 三个类,类的数量的增长率有 30% 之多。
这种模式的应用场景比较少,大家要从源码里找的话,可以结合《Android 源码设计模式解析与实战》看一下 Android 底层对 MediaPlayer 的处理。
另外,Android 常见功能 主题切换 很适合应用此设计模式。
本讲的示例源码已经放在 Gihub 上:AbstractFactoryPattern
感谢
- 《Android源码设计模式解析与实战》 何红辉 关爱民
- 在线绘图网站 ProcessOn