天天看點

設計模式----Abstract Factory 抽象工廠

作者:初春de小草
設計模式----Abstract Factory 抽象工廠

動機(Motivation)

在軟體系統中,經常面臨着“一系列互相依賴的對象”的建立工作;同時,由于需求的變化,往往存在更多系列對象的建立工作。

如何應對這種變化?如何繞過正常的對象建立方法(new),提供一種“封裝機制”來避免客戶程式和這種“多系列具體對象建立工作”的緊耦合?

1.在代碼上看什麼是“一系列互相依賴的對象”

//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>

using namespace std;

//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計
class EmployeeDAO
{
public:
	vector<EmployeeDA> GetEmployee()
	{
		//Sql的連接配接對象
		SqlConnection* connection = new SqlConnection();
		connection->ConnectionString = "...";

		//Sql指令對象
		SqlCommand* command = new SqlCommand();
		command->CommandText = "...";
		command->SetConnection(connection);

		//Sql的讀取對象
		SqlDataReader* reader = command->ExecuteReader();
		while (reader->Read())
		{
		}
	}

};           
//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>

using namespace std;

//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計

//改進--建立一系列的基礎類
//資料庫通路有關的基類
class IDBConnection
{
};
class IDBCommand
{
};
class IDataReader
{
};

//三個工廠特别有相關性,就做成一個工廠,高内聚 松耦合
class IDBFactory
{
public:
	virtual IDBConnection* CreateDBConnection() = 0;
	virtual IDBCommand* CreateDBCommand() = 0;
	virtual IDataReader* CreateDataReader() = 0;
};


//支援Sql的
class SqlDBConnection :public IDBConnection
{
};
class SqlDBCommand :public IDBCommand
{
};
class SqlDBDataReader :public IDataReader
{
};

class SqlDBFactory :public IDBFactory
{
public:
	virtual IDBConnection* CreateDBConnection() = 0;
	virtual IDBCommand* CreateDBCommand() = 0;
	virtual IDataReader* CreateDataReader() = 0;

};

//支援Oracle的
class OracleDBConnect :public IDBConnection
{
};
class OracleDBCommand :public IDBCommand
{
};
class OracleDBDataReader :public IDataReader
{
};

class OraclDBFactory :public IDBFactory
{
public:
	virtual IDBConnection* CreateDBConnection() = 0;
	virtual IDBCommand* CreateDBCommand() = 0;
	virtual IDataReader* CreateDataReader() = 0;

};









//到目前為止,勉強解決問題,暴露出來的問題:
//三個工廠對象必須是同系列的,都是MySql或者都是SqlServer----》解決方式Abstractor Factory抽象工廠(家族工廠)
class EmployeeDAO
{
	IDBFactory* dbFactory;
public:
	vector<EmployeeDO> GetEmployee()
	{
		//Sql的連接配接對象    //new有問題--立馬想到 Factory Method方法
		IDBConnection* connection = dbFactory->CreateDBConnection();
		connection->ConnectionString("...");

		//Sql指令對象
		IDBCommand* command = dbFactory->CreateDBCommand();
		command->CommandText("...");
		command->SetConnection(connection);//關聯性

		//Sql的讀取對象
		IDataReader* reader = command->ExecuteReader();//關聯性
		while (reader->Read())
		{
		}
	}

};
           
//EmployeeDAO1.cpp
#include <iostream>
#include <stdlib.h>

using namespace std;

//寫一個資料通路層,要建立一系列的對象
//本類不使用于MySql Oracle DB2等資料庫的通路,要支援多種資料庫呢,就要想到面向接口的程式設計

//改進--建立一系列的基礎類
//資料庫通路有關的基類
class IDBConnection
{
};
class IDBConnectionFactory
{
	virtual IDBConnection* CreateDBConnection() = 0;
};


class IDBCommand
{

};
class IDBCommandFactory
{
	virtual IDBCommand* CreateDBCommand() = 0;
};


class IDataReader
{

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


//支援Sql的
class SqlConnection :public IDBConnection
{

};
class SqlConnectFactory :public IDBConnectionFactory
{

};

class SqlCommand :public IDBCommand
{

};
class SqlCommandFactory :public IDBCommandFactory
{

};


class SqlDataReader :public IDataReader
{

};
class SqlDataReaderFactory :public IDBConnectionFactory
{

};

//支援Oracle的
class OracleConnect :public IDBConnection
{

};
class OracleConnectFactory :public IDBConnectionFactory
{

};

class OracleCommand :public IDBCommand
{

};
class OracleCommandFactory :public IDBCommandFactory
{

};

class OracleDataReader :public IDataReader
{

};
class OracleDataReaderFactory :public IDataReaderFactory
{

};









//到目前為止,勉強解決問題,暴露出來的問題:
//三個工廠對象必須是同系列的,都是MySql或者都是SqlServer----》解決方式Abstractor Factory
class EmployeeDAO
{
	IDBConnectionFactory* dbConnectionFactory;
	IDBCommandFactory* dbCommandFactory;
	IDataReaderFactory* dbReaderFacotory;
public:
	vector<EmployeeDO> GetEmployee()
	{
		//Sql的連接配接對象    //new有問題--立馬想到 Factory Method方法
		IDBConnection* connection = dbConnectionFactory->CreateDBConnection();
		connection->ConnectionString("...");

		//Sql指令對象
		IDBCommand* command = dbCommandFactory->CreateDBCommand();
		command->CommandText("...");
		command->SetConnection(connection);

		//Sql的讀取對象
		IDataReader* reader = command->ExecuteReader();
		while (reader->Read())
		{
		}
	}

};
           

模式定義

提供一個接口,讓該接口負責建立一系列“相關或者互相依賴的對象”,無需指定他們具體的類。

----《設計模式》GoF

設計模式----Abstract Factory 抽象工廠

要點總結

如果沒有應對“多系列對象建構”的需求變化,則沒有必要使用Abstract Factory模式,這時候使用簡單的工廠完全可以。

“系列對象”指的是在某一特定系列下的對象之間有互相依賴、或作用的關系。不同系列的對象之間不能互相依賴。

Abstract Factory 模式主要在于對應“新系列”的需求變動。其确定在于難以應對“新對象”的需求變動。

繼續閱讀