抽象工廠方法是工廠方法模式的延伸,它提供了功能更爲強大的工廠類而且具有較好的可擴展性;sql
一、抽象工廠模式隔離了具體類的生成,使得客戶端並不須要知道什麼被建立。數據庫
二、當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一產品族中的對象;設計模式
三、增長新的產品族很方便,無需修改已有系統代碼,符合開閉原則;spa
缺點:設計
一、增長新的產品等級結構麻煩,須要對原有系統進行較大的修改,甚至須要修改抽象層代碼,違背了開閉原則;code
適用環境:對象
一、用戶無需關心對象的建立過程,將對象的建立和使用解耦;blog
二、產品等級結構穩定,在設計完成以後不會向系統中增長新的產品等級結構或者刪除已有的產品等級結構; 產品
三、系統中有多於一個的產品族,而每次只使用其中某一產品族。能夠經過配置文件等方式來使用戶可以動態改變產品族,也能夠很方便的增長新的產品族;io
代碼一(未經設計模式更改的代碼):
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()){ } } };
如今有需求了,就是想讓該數據庫操做適合DB二、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()){ } } };