抽象工厂模式
# 一、概述
抽象工厂(Abstract Factory)模式为你提供了一个接口,可用于创建每个系列产品的对象。只要代码通过该接口创建对象,那么你就不会生成与应用程序已生成的产品类型不一致的产品。
# 1.1 解决了什么问题
假设富士康总部有两个组员工,其中 A 组专注于手机生产,B 组专注于电脑生产,两个组各有所长。突然有一天富士康同时收到了苹果和小米的手机订单与电脑订单,如果将同时将两家公司的手机订单和电脑订单交给 A 组和 B 组生产是有风险的。两个品牌本来就是竞争关系,同一个组在生产两个品牌的产品,万一泄密了怎么办,万一将零件搞混了怎么办。而且后续还可能会接到苹果和小米的其它订单,比如耳机、充电宝、显示器等。
# 1.2 解决方案
针对上述问题,最好的方式就是针对苹果和小米分别创建两个子工厂,同时将 A、B 两个组的人也分散到两个子工厂。苹果工厂的 A 组员工专注于生产 iPhone,小米工厂的 A 组员工专注于生产小米手机,苹果工厂的 B 组员工专注于生产 Mac,小米工厂的 B 组员工专注于生产小米笔记本。后续如果同时接到了两家公司的其它产品订单,也是按照这种方式,不同品牌的产品由其相应的工厂进行生产。
抽象工厂模式就是专注于解决有“品牌产品家族”生产概念的问题。
# 二、实现方式
# 2.1 角色
抽象工程包含四个角色,和工厂方法相同,但是一个工厂可以创建多种产品:
- 抽象工厂:是具体工厂角色必须继承的类或实现的接口。
- 具体工厂:由应用程序调用用来创建具体的产品对象。
- 抽象产品:具体产品要继承的类或实现的接口。
- 具体产品:具体工厂所创建的对象,是一个具体的产品实例。
# 2.2 代码
定义电脑接口,基于电脑接口定义苹果电脑和小米电脑具体类:
interface Computer {
/**
* 安装屏幕
*/
void setScreen();
/**
* 安装电池
*/
void setBattery();
}
class MacBook implements Computer {
@Override
public void setScreen() {
System.out.println("为苹果电脑安装屏幕");
}
@Override
public void setBattery() {
System.out.println("为苹果电脑安装电池");
}
}
class XiaomiComputer implements Computer {
@Override
public void setScreen() {
System.out.println("为小米电脑安装屏幕");
}
@Override
public void setBattery() {
System.out.println("为小米电脑安装电池");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
同理,定义手机接口并基于手机接口定义苹果手机和小米手机具体类:
interface Phone {
/**
* 安装屏幕
*/
void setScreen();
/**
* 安装电池
*/
void setBattery();
}
class IPhone implements Phone {
@Override
public void setScreen() {
System.out.println("为苹果手机安装屏幕");
}
@Override
public void setBattery() {
System.out.println("为苹果手机安装电池");
}
}
class XiaomiPhone implements Phone {
@Override
public void setScreen() {
System.out.println("为小米手机安装屏幕");
}
@Override
public void setBattery() {
System.out.println("为小米手机安装电池");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
定义抽象工厂类,抽象工厂类中只定义抽象产品,而不是具体的产品。
interface AbstractFactory {
/**
* 工厂生产电脑接口
*
* @return
*/
Computer makeComputer();
/**
* 共产生产手机接口
*
* @return
*/
Phone makePhoto();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
基于抽象工厂,定义两个子工厂,在子工厂的方法中实现具体的生产需求:
class AppleFactory implements AbstractFactory {
@Override
public Computer makeComputer() {
return new MacBook();
}
@Override
public Phone makePhoto() {
return new IPhone();
}
}
class XiaoMiFactory implements AbstractFactory {
@Override
public Computer makeComputer() {
return new XiaomiComputer();
}
@Override
public Phone makePhoto() {
return new XiaomiPhone();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
使用示例:
public class AbstractFactoryTest {
public static void main(String[] args) {
// 苹果工厂
AppleFactory appleFactory = new AppleFactory();
Computer appleComputer = appleFactory.makeComputer();
Phone iphone = appleFactory.makePhoto();
appleComputer.setScreen();
appleComputer.setBattery();
iphone.setScreen();
iphone.setBattery();
// 小米工厂
XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
Computer xiaomiComputer = xiaoMiFactory.makeComputer();
Phone xiaomiPhone = xiaoMiFactory.makePhoto();
xiaomiComputer.setScreen();
xiaomiComputer.setBattery();
xiaomiPhone.setScreen();
xiaomiPhone.setBattery();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 三、三种工厂模式对比
简单工厂模式是最简单的一种,其核心是只有一个工厂类,且该工厂类中提供了一个静态工厂方法,有客户端直接向工厂类传递参数,工厂类根据不同参数实例化相应类型的对象。
工厂方法模式的核心是针对每个不同的产品都各自创建一个工厂类,该工厂只能生产这种特定的产品。客户端根据需要的产品类型创建不同的工厂实例,然后由工厂实例创建产品。这种方式使用比较繁琐,因为每新增一种产品就需要新建一个工厂类。
抽象工厂模式非常适合有“品牌产品家族”概念的场景,针对每个“品牌”创建一个工厂实例,然后由该工厂实例创建其品牌下的一系列产品。和工厂方法模式不同的是,抽象工厂模式是有产品家族概念的,一个工厂可以生产多款产品,而工厂方法模式中一个工厂可以生产多款产品。