C++設計模式 - 抽象工廠(Abstract Factory)
阿新 • • 發佈:2022-03-14
物件建立模式
通過“物件建立” 模式繞開new,來避免物件建立(new)過程中所導致的緊耦合(依賴具體類),從而支援物件建立的穩定。它是介面抽象之後的第一步工作。
典型模式
- Factory Method
- Abstract Factory
- Prototype
- Builder
Abstract Factory
動機(Motivation)
- 在軟體系統中,經常面臨著“一系列相互依賴的物件”的建立工作;同時,由於需求的變化,往往存在更多系列物件的建立工作。
- 如何應對這種變化?如何繞過常規的物件建立方法(new),提供一種“封裝機制”來避免客戶程式和這種“多系列具體物件建立工作”的緊耦合?
模式定義
提供一個介面,讓該介面負責建立一系列“相關或者相互依賴的物件”,無需指定它們具體的類。
結構
總結
- 如果沒有應對“多系列物件構建”的需求變化,則沒有必要使用Abstract Factory模式,這時候使用簡單的工廠完全可以。
- “系列物件”指的是在某一特定系列下的物件之間有相互依賴、或作用的關係。不同系列的物件之間不能相互依賴。
- Abstract Factory模式主要在於應對“新系列”的需求變動。其缺點在於難以應對“新物件”的需求變動。
cpp
#include<iostream> class IDBConnection { public: virtual void ConnectionString() = 0; virtual ~IDBConnection() {} }; class IDBCommand { public: virtual void SetConnection() = 0; virtual ~IDBCommand() {} }; class IDataReader { public: virtual void Read() = 0; virtual ~IDataReader() {} }; //支援SQL Server class SqlConnection : public IDBConnection { public: virtual void ConnectionString() { std::cout << "SqlConnection" << std::endl; } }; class SqlCommand : public IDBCommand { public: virtual void SetConnection() { std::cout << "SqlCommand" << std::endl; } }; class SqlDataReader : public IDataReader { public: virtual void Read() { std::cout << "SqlDataReader" << std::endl; } }; //支援Oracle class OracleConnection : public IDBConnection { public: virtual void ConnectionString() { std::cout << "OracleConnection" << std::endl; } }; class OracleCommand : public IDBCommand { public: virtual void SetConnection() { std::cout << "OracleCommand" << std::endl; } }; class OracleDataReader : public IDataReader { public: virtual void Read() { std::cout << "OracleDataReader" << std::endl; } }; class IDBFactory { public: virtual IDBConnection* CreateDBConnection() = 0; virtual IDBCommand* CreateDBCommand() = 0; virtual IDataReader* CreateDataReader() = 0; }; class SqlDBFactory :public IDBFactory { public: virtual IDBConnection* CreateDBConnection() { return new SqlConnection(); } virtual IDBCommand* CreateDBCommand() { return new SqlCommand(); } virtual IDataReader* CreateDataReader() { return new SqlDataReader(); } }; class OracleDBFactory :public IDBFactory { public: virtual IDBConnection* CreateDBConnection() { return new OracleConnection(); } virtual IDBCommand* CreateDBCommand() { return new OracleCommand(); } virtual IDataReader* CreateDataReader() { return new OracleDataReader(); } }; class EmployeeDAO { private: IDBFactory* dbFactory; public: EmployeeDAO(IDBFactory* dbfactory) { this->dbFactory = dbfactory; } void GetEmployees() { IDBConnection* connection = dbFactory->CreateDBConnection(); connection->ConnectionString(/*"..."*/); IDBCommand* command = dbFactory->CreateDBCommand(); command->SetConnection(/*"connection"*/); //關聯性 IDataReader* reader = dbFactory->CreateDataReader(); reader->Read(); } }; int main() { IDBFactory* factoryA = new SqlDBFactory(); EmployeeDAO* dbA = new EmployeeDAO(factoryA); dbA->GetEmployees(); IDBFactory* factoryB = new OracleDBFactory(); EmployeeDAO* dbB = new EmployeeDAO(factoryB); dbB->GetEmployees(); return 0; }