本文主要介绍抽象工厂模式(Abstract Factory Pattern),它的定义是:“提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。”。
1. 模式介绍
工厂模式(Factory Design Pattern)是一种极为常用的用于创建对象的设计模式,在绝大部份开源框架中都有最佳实践,最为人所知的大概就是 Spring 的 BeanFactory 了。
工厂模式属于创建型模式,事实上它有三种不同的实现方式:简单工厂模式、工厂方法模式、抽象工厂模式。
本文主要介绍抽象工厂模式(Abstract Factory Pattern),它的定义是:“提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。”。
抽象工厂模式是工厂方法模式的升级版,在抽象工厂模式中,抽象工厂接口有若干个方法需要具体工厂类实现。换言之,抽象工厂模式中的工厂类可以创建多个对象,同时这多个对象没有继承、实现接口的关系。
2. 应用场景
抽象工厂模式适用的场景是:一类对象,或者是一类没有具体关系的对象,如果拥有着相同的约束,那么就可以使用抽象工厂模式。
本段话摘自《设计模式之禅》(第2版)9.3.3 抽象工厂模式的使用场景
3. 类图
抽象工厂方法模式中有四种角色:
- 抽象产品(IProduct):描述了工厂创建的所有对象的抽象接口
- 具体产品(Concrete Product):工厂创建的具体实例,实现了抽象产品接口
- 抽象工厂(Abstract Factory):描述了工厂创建具体产品的方法,任何用来创建具体产品的工厂类必须实现该接口
- 具体工厂(Concrete Factory):创建具体产品的具体工厂类,实现了抽象工厂,描述了创建某个指定类型的具体产品的过程
这四种角色与工厂方法模式是一样的,但是抽象工厂模式与工厂方法模式的区别就在于:抽象工厂模式中,一个工厂可以创建多种类型的对象,而工厂方法模式中,一个工厂只能创建一种类型的对象。
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版)
最后,本文收录于个人语雀知识库: 我所理解的后端技术,欢迎来访。
文档信息
- 本文作者:Planeswalker23
- 本文链接:https://planeswalker23.github.io/2022/01/20/%E6%88%91%E6%89%80%E7%90%86%E8%A7%A3%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97-%E7%AC%AC2.3%E7%AF%87-%E4%B8%89%E7%A7%8D%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85%E6%A5%9A(3)%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/
- 版权声明:本作品系原创,作者保留所有权利,未经作者允许,禁止转载和演绎。