创建型设计模式的一种

建议先看工厂模式

举例

从一个例子入手更容易理解。

仍然使用工厂模式中的数据模型的例子,假设由于历史原因,对每一个模型的操作都有两个服务,分别用于查询和修改,代码如下(省略具体方法):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 查询接口
*/
public interface IQueryService {}
/**
* 二维模型查询实现类
*/
public class TwoDimQueryService implements IQueryService {}
/**
* 多维模型查询实现类
*/
public class MultiDimQueryService implements IQueryService {}

/**
* 修改接口
*/
public interface IUpdateService {}
/**
* 二维模型修改实现类
*/
public class TwoDimUpdateService implements IUpdateService {}
/**
* 多维模型修改实现类
*/
public class MultiDimUpdateService implements IUpdateService {}

那么怎么能够做到让客户端不用关心在执行查询或修改时调用的哪个实现类的方法呢? 这就需要使用抽象工厂模式,代码如下:

1
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* 工厂接口
*/
public interface IFactory {
IQueryService createQueryService();
IUpdateService createUpdateService();
}
/**
* 二维模型工厂类
*/
public class TwoDimSrvFactory implements IFactory {
@Override
public IQueryService createQueryService() {
return new TwoDimQueryService();
}
@Override
public IUpdateService createUpdateService() {
return new TwoDimUpdateService();
}
}
/**
* 多维模型工厂类
*/
public class MultiDimSrvFactory implements IFactory {
@Override
public IQueryService createQueryService() {
return new MultiDimQueryService();
}
@Override
public IUpdateService createUpdateService() {
return new MultiDimUpdateService();
}
}

/**
* 客户端类
*/
public class Main {
public static void main() {
Model model = new TwoDimModel();
// Model model = new MultiDimModel();
// 工厂
IFactory factory = new TwoDimSrvFactory();

// 查询服务
IQeuryService querySrv = factory.createQueryService();
// 修改服务
IUpdateService updateSrv = factory.createUpdateService();
}
}

可以看到,客户端只需要知道是哪个工厂类即可,工厂类中的是对查询和修改的抽象接口。

上述例子的类图

抽象工厂模式类图)

该类图的核心是工厂接口包括了创建查询服务和修改服务的方法,让具体的工厂类分别实现。因为工厂接口只指定方法,因此叫“抽象工厂模式”。

【DP】定义

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

使用场景

  1. 需要一个接口可以提供一个产品族(即上文说的对不同的模型的服务操作),且不必知道产品的具体种类

注意事项

  1. 工厂模式和抽象工厂模式的区别是: 工厂模式只需要提供单一的产品(针对例子中的是模型服务),而抽象工厂模式针对的产品族(针对例子中的是模型的一套服务)。
  2. 可以看到,仍然存在如果增加不同类型的模型后,在客户端的调用要修改的问题,因此需要使用简单工厂模式+抽象工厂模式