Abstract Factory 抽象工厂
动机(Motivation)
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来规避客户程序和这种“多系列具体对象创建工作”的紧耦合?
接口定义
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
示例1
#pragma once
#include <vector>
#include <string>
using namespace std;
class EmployeeDO {
};
class SqlConnection {
public:
string connect_string;
};
class SqlDataReader {
public:
bool Read() {
return false;
}
};
class SqlCommand {
public:
string connect_text;
void SetConnection(SqlConnection* sql_connection) {
}
SqlDataReader* ExecuteReader() {
return new SqlDataReader();
}
};
class EmployeeDAO {
public:
vector<EmployeeDO> GetEmployees() {
SqlConnection* connection =
new SqlConnection();
connection->connect_string = "...";
SqlCommand* command
= new SqlCommand();
command->connect_text = "...";
command->SetConnection(connection);
SqlDataReader* reader = command->ExecuteReader();
while (reader->Read()) {
//...
}
}
};
示例2
#pragma once
#include <vector>
#include <string>
using namespace std;
class EmployeeDO {
};
class IDBConnection {
};
class IDBCommand
{
public:
virtual ~IDBCommand() {}
public:
void SetDBconnection(IDBConnection* db_connection) {
db_connection_ = db_connection;
}
virtual IDBReader* ExecuteReader() = 0;
private:
IDBConnection* db_connection_;
};
class IDBReader {
public:
virtual ~IDBReader() {}
};
//SQL server
class SqlConnection : public IDBConnection {
};
class SqlCommand : public IDBCommand {
public:
virtual IDBReader* ExecuteReader() {
return new SqlReader();
}
};
class SqlReader : public IDBReader {
};
//Oracle
class OracleConnection : public IDBConnection {
};
class OracleCommand : public IDBCommand {
public:
virtual IDBReader* ExecuteReader() {
return new OracleReader();
}
};
class OracleReader : public IDBReader {
};
class IDBFactory {
public:
virtual IDBConnection* CreateDBConnect() = 0;
virtual IDBCommand* CreateDBCommand() = 0;
virtual IDBReader* CreateDBReader() = 0;
};
class SqlDBFactory : public IDBFactory {
public:
virtual IDBConnection* CreateDBConnect() {
return new SqlConnection();
}
virtual IDBCommand* CreateDBCommand() {
return new SqlCommand();
}
virtual IDBReader* CreateDBReader() {
return new SqlReader();
}
};
class OracleDBFactory : public IDBFactory {
public:
virtual IDBConnection* CreateDBConnect() {
return new OracleConnection();
}
virtual IDBCommand* CreateDBCommand() {
return new OracleCommand();
}
virtual IDBReader* CreateDBReader() {
return new OracleReader();
}
};
class EmployeeDAO {
IDBFactory* db_factory_;
public:
vector<EmployeeDO> GetEmployees() {
IDBConnection* connection =
db_factory_->CreateDBConnect();
IDBCommand* command
= db_factory_->CreateDBCommand();
command->SetDBconnection(connection);
IDBReader* reader = command->ExecuteReader();
//IDBReader* reader = db_factory_->CreateDBReader();
// ...
}
};
要点总结
如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Facory模式,这时候使用简单的工厂完全可以。
“系列对象”指的是在某一特定系列下的对象之间有相互依赖或作用的关系。不同系列的对象之间不能相互依赖。
Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变化。