【C++设计模式】4.7-抽象工厂(Abstract Factory)

一、 抽象工厂(Abstract Factory)

1. 模式动机

    在软件系统中,经常面临着 “一系列相互依赖的对象” 的创建工作。同时,由于需求的变化,往往存在更多系列对象的创建工作。
    如何应对这种系列变化?如何绕过常规的对象创建方法(new),提供一种封装机制来避免客户程序和这种 “多系列具体对象创建工作” 的紧耦合?

2. 模式定义

    提供一个接口,让该接口负责创建一系列 “相关或者相互依赖的对象”,无需指定它们具体的类。

3. 要点总结

(1)如果没有应对 “多系列对象构建” 的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。
(2)“系列对象” 指的是在某一特定系列下的对象之间有相互依赖、或作用的关系,不同系列的对象之间不能相互依赖。
(3)Abstract Factory模式主要在于应对 “新系列” 的需求变动。其缺点在于难以应对 “新对象” 的需求变动。

三、实现

代码

    

重构前

/**
 * 使用普通的工厂模式
 */
//数据库访问有关的基类
class IDBConnection{};
class IDBConnectionFactory{
public:
	virtual IDBConnection* createDBConnection() = 0;
};

class IDBCommand{};
class IDBCommandFactory{
public:
	virtual IDBCommand* createDBCommand() = 0;
};

class IDataReader{};
class IDataReaderFactory{
public:
	virtual IDataReader* CreateDataReader() = 0;
};

//支持Mysql
class SqlConnection : public IDBConnection{};
class SqlConnectionFactory : public IDBConnectionFactory{};

class SqlCommand : public IDBCommand{};
class SqlCommandFactory : public IDBCommandFactory{};

class SqlDataReader : public IDataReader{};
class SqlDataReaderFactory : public IDataReaderFactory{};

//支持Oracle
class OracleConnection : public IDBConnection{};
class OracleConnectionFactory : public IDBConnectionFactory{};

class OracleCommand : public IDBCommand{};
class OracleConnectionFactory : public IDBCommandFactory{};

class OracleDataReader : public IDataReader{};
class OracleConnectionFactory : public IDataReaderFactory{};

class EmployeeDAO{
	IDBConnectionFactory* dbConnectionFactory;
	IDBCommandFactory* dbCommandFactory;
	IDataReaderFactory* dbReaderFactory;
public:
	/** 不用接口和工厂模式时会发现这样写依赖了具体类
	vector<EmployeeDD> GetEmployees(){
		SqlConnection* connection = new SqlConnection();
		connection->ConnectionString("...");
		SqlCommand* command = new SqlCommand();
		command->CommandText("...");
	}
	*/
	vector<EmployeeDD> GetEmployees(){
		IDBConnection* connection = dbConnectionFactory->createDBConnection();
		connection->ConnectionString("...");
		IDBCommand* command = dbCommandFactory->createDBCommand();
		command->CommandText("...");
		command->SetConnection(connection);					//关联性
		IDataReader* reader = command->ExecuteReader();		//关联性
		while (reader->Read()){
		
		}
	}
};

抽象工厂模式类图

    下面是使用了抽象工厂方法模式的类图及其对应重构后代码中的类图。

重构后

//数据库访问有关的基类
class IDBConnection{};
class IDBCommand{};
class IDataReader{};

class IDBFactory{	//把三个工厂合成一个工厂了
public:
	virtual IDBConnection* createDBConnection() = 0;
	virtual IDBCommand* createDBConnection() = 0;
	virtual IDataReader* createDataReader() = 0;
};
//支持Mysql
class SqlConnection : public IDBConnection{};
class SqlCommand : public IDBCommand{};
class SqlDataReader : public IDataReader{};
class SqlDBFactory : public IDBFactory{
	virtual IDBConnection* createDBConnection() = 0;
	virtual IDBCommand* createDBCommand() = 0;
	virtual IDataReader* createDataReader() = 0;
};
//支持Oracle
class OracleConnection : public IDBConnection{};
class OracleCommand : public IDBCommand{};
class OracleDataReader : public IDataReader{};
class OracleDBFactory : public IDBFactory{
	virtual IDBConnection* createDBConnection() = 0;
	virtual IDBCommand* createDBCommand() = 0;
	virtual IDataReader* createDataReader() = 0;
};
class EmployeeDAO{
	IDBFactory* dbFactory;								//得到了关联性的保证,同一种数据库
public:
	vector<EmployeeDD> GetEmployees(){
		IDBConnection* connection = dbFactory->createDBConnection();
		connection->ConnectionString("...");
		IDBCommand* command = dbFactory->createDBCommand();
		command->CommandText("...");
		command->SetConnection(connection);					//关联性
		IDataReader* reader = command->ExecuteReader();		//关联性
		while (reader->Read()){
		
		}
	}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值