概述:
抽象工厂方法是工厂方法模式的延伸,它提供了功能更为强大的工厂类并且具备较好的可扩展性;
优点:
1、抽象工厂模式隔离了具体类的生成,使得客户端并不需要知道什么被创建。
2、当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一产品族中的对象;
3、增加新的产品族很方便,无需修改已有系统代码,符合开闭原则;
缺点:
1、增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了开闭原则;
适用环境:
1、用户无需关心对象的创建过程,将对象的创建和使用解耦;
2、产品等级结构稳定,在设计完成之后不会向系统中增加新的产品等级结构或者删除已有的产品等级结构;
3、系统中有多于一个的产品族,而每次只使用其中某一产品族。可以通过配置文件等方式来使用户能够动态改变产品族,也可以很方便的增加新的产品族;
代码一(未经设计模式更改的代码):
EmployeeDAO1.cpp
class EmployeeDAO{ public: vector<EmployeeDAO> GetEmployees(){ SqlConnectionn connection = new SqlConnection(); //建立数据库的连接 connnection->ConnectionString = "..."; SqlCommand* command = new SqlCommand(); //建立数据库的命名对象 command->CommandText = "..."; commend->SetConnection(connection); SqlDataReader* reader = command->ExcuteReader(); while (reader->Read()){ } } };
现在有需求了,就是想让该数据库操作适合DB2、Oracle、Mysql等数据库,该普通工厂的方法为
EmployeeDAO2.cpp
//数据库访问有关的基类 class IDBConnection{ }; class IDBConnectionFactory{ public: virtual IDBConnection* CreateDBConnection() = 0; }; class IDBConmmand{ }; class IDBConmmandFactory{ public: virtual IDBConmmand* CreateDBConmmand() = 0; }; class IDataReader{ }; class IDataReaderFactory{ public: virtual IDataReader* CreateDataReader() = 0; }; //支持SQL Server class SqlConnection :public IDBConnection{ }; class SqlConnectionFactory :public IDBConnectionFactory{ }; class SqlCommand :public IDBConmmand{ }; class SqlCommandFactory :public IDBConmmandFactory{ }; class SqlDataReader :public IDataReader{ }; class SqlDataReaderFactory :public IDataReaderFactory{ }; //支持 Oracle class OracleConnection :public IDBConnection{ }; class OracleCommand :public IDBConmmand{ }; class OracleDataReader :public IDataReader{ }; class EmployeeDAO{ IDBConnectionFactory* dbConnectionFactory; IDBConmmandFactory* dbConmmandFactory; IDataReader* dataReaderFactory; public: vector<EmployeeDAO> GetEmployees(){ IDBConnection connection = dbConnectionFactory->CreateDBConnection; //建立数据库的连接 connnection->ConnectionString = "..."; IDBCommand* command = dbConmmandFactory->CreateDBConmmand; //建立数据库的命名对象 command->CommandText = "..."; commend->SetConnection(connection); IDBDataReader* reader = command->ExcuteReader(); while (reader->Read()){ } } };
为了让上面的代码更简洁些,也就是所谓的“系列对象”的问题,可以用抽象工厂方法
EmployeeDAO3.cpp
//数据库访问有关的基类 class IDBConnection{ }; class IDBConmmand{ }; class IDataReader{ }; class IDBFactory{ public: virtual IDBConnection* CreateDBConnection() = 0; virtual IDBConmmand* CreateDBConmmand() = 0; virtual IDataReader* CreateDataReader() = 0; }; //支持SQL Server class SqlConnection :public IDBConnection{ }; class SqlCommand :public IDBConmmand{ }; class SqlDataReader :public IDataReader{ }; class SqlDBFactory :public IDBFactory{ virtual IDBConnection* CreateDBConnection() = 0; virtual IDBConmmand* CreateDBConmmand() = 0; virtual IDataReader* CreateDataReader() = 0; }; //支持 Oracle class OracleConnection :public IDBConnection{ }; class OracleCommand :public IDBConmmand{ }; class OracleDataReader :public IDataReader{ }; class EmployeeDAO{ IDBFactory* dbFactory; public: vector<EmployeeDAO> GetEmployees(){ IDBConnection connection = dbFactory->CreateDBConnection; //建立数据库的连接 connnection->ConnectionString = "..."; IDBCommand* command = dbFactory->CreateDBConmmand; //建立数据库的命名对象 command->CommandText = "..."; commend->SetConnection(connection); IDBDataReader* reader = command->ExcuteReader(); while (reader->Read()){ } } };