5.2 抽象工厂模式
动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
代码示例:
实现利用数据库的业务逻辑,支持多数据库(Sql,Oracle等),有连接、命令、读取等功能。
其中命令,连接功能之间有相互联系。
方法一(使用工厂方法):
每个功能类有一个创建的工厂,如IDBConnection与IDBConnectionFactory
1 //数据库访问有关的基类
2 class IDBConnection{
3
4 };
5 class IDBConnectionFactory{
6 public:
7 virtual IDBConnection* CreateDBConnection()=0;
8 };
9
10
11 class IDBCommand{
12
13 };
14 class IDBCommandFactory{
15 public:
16 virtual IDBCommand* CreateDBCommand()=0;
17 };
18
19
20 class IDataReader{
21
22 };
23 class IDataReaderFactory{
24 public:
25 virtual IDataReader* CreateDataReader()=0;
26 };
27
28
29 //支持SQL Server
30 class SqlConnection: public IDBConnection{
31
32 };
33 class SqlConnectionFactory:public IDBConnectionFactory{
34
35 };
36
37
38 class SqlCommand: public IDBCommand{
39
40 };
41 class SqlCommandFactory:public IDBCommandFactory{
42
43 };
44
45
46 class SqlDataReader: public IDataReader{
47
48 };
49 class SqlDataReaderFactory:public IDataReaderFactory{
50
51 };
52
53 //支持Oracle
54 class OracleConnection: public IDBConnection{
55
56 };
57
58 class OracleCommand: public IDBCommand{
59
60 };
61
62 class OracleDataReader: public IDataReader{
63
64 };
65
66
67
68 class EmployeeDAO{
69 IDBConnectionFactory* dbConnectionFactory;
70 IDBCommandFactory* dbCommandFactory;
71 IDataReaderFactory* dataReaderFactory;
72
73
74 public:
75 vector<EmployeeDO> GetEmployees(){
76 IDBConnection* connection =
77 dbConnectionFactory->CreateDBConnection(...);
78 connection->ConnectionString("...");
79
80 IDBCommand* command =
81 dbCommandFactory->CreateDBCommand(...);
82 command->CommandText("...");
83 command->SetConnection(connection); //关联性
84
85 IDBDataReader* reader = command->ExecuteReader(); //关联性
86 while (reader->Read()){
87
88 }
89
90 }
91 };
分析上述代码,虽然解决了组件创建的问题。但是仔细考虑,由于功能之间具有关联性,不同类型数据库的对象并不能同时创建搭配(如sql的command和oracle的connection搭配,显然不合理)。所以考虑抽象工厂模式。见方法二:
使用一个工厂,将一系列相互依赖的的对象创建在一个工厂中实现。
1 //数据库访问有关的基类
2 class IDBConnection{
3
4 };
5
6 class IDBCommand{
7
8 };
9
10 class IDataReader{
11
12 };
13
14
15 class IDBFactory{
16 public:
17 virtual IDBConnection* CreateDBConnection()=0;
18 virtual IDBCommand* CreateDBCommand()=0;
19 virtual IDataReader* CreateDataReader()=0;
20
21 };
22
23
24 //支持SQL Server
25 class SqlConnection: public IDBConnection{
26
27 };
28 class SqlCommand: public IDBCommand{
29
30 };
31 class SqlDataReader: public IDataReader{
32
33 };
34
35
36 class SqlDBFactory:public IDBFactory{
37 public:
38 virtual IDBConnection* CreateDBConnection()=0;
39 virtual IDBCommand* CreateDBCommand()=0;
40 virtual IDataReader* CreateDataReader()=0;
41
42 };
43
44 //支持Oracle
45 class OracleConnection: public IDBConnection{
46
47 };
48
49 class OracleCommand: public IDBCommand{
50
51 };
52
53 class OracleDataReader: public IDataReader{
54
55 };
56
57
58
59 class EmployeeDAO{
60 IDBFactory* dbFactory;
61
62 public:
63 vector<EmployeeDO> GetEmployees(){
64 IDBConnection* connection =
65 dbFactory->CreateDBConnection();
66 connection->ConnectionString("...");
67
68 IDBCommand* command =
69 dbFactory->CreateDBCommand();
70 command->CommandText("...");
71 command->SetConnection(connection); //关联性
72
73 IDBDataReader* reader = command->ExecuteReader(); //关联性
74 while (reader->Read()){
75
76 }
77
78 }
79 };
模式定义:
提供一个接口,让该接口复杂创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。
类图:
要点总结:
如果没有应对”多系列对象构建“的需求变化,则没有必要使用Abstract Factory模式,这是要使用工厂方法即可。
”系列对象“指的是某一特定系列下的对象之间有相互依赖或作用的关系。不同系列的对象之间不能相互依赖。
Abstract Factory模式主要在于应对”新系列“的需求变动。其缺点在于难以应对”新对象“的需求变动。
原文链接: https://www.cnblogs.com/wangxiaobao/p/5222863.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/229249
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!