大話設計模式C++實現-第15章-抽象工廠模式

一、UML圖



二、概念

抽象方法模式(Abstract Factory):提供一個創建一系列相關或互相依賴對象的接口,而無需指定他們具體的類。


三、包含的角色

(1)抽象工廠

(2)具體工廠:包括具體工廠1和具體工廠2。具體工廠1用於生產具體產品A1和具體產品B1,具體工廠2用於生產具體產品A2和具體產品B2;

(3)抽象產品:包括抽象產品A和抽象產品B;

(4)具體產品:包括抽象產品A所對應的具體產品A1和A2,以及抽象產品B所對應的具體產品B1和B2.

說明:在《大話設計模式》中,上述的1和2分別代表Sqlserver數據庫和Access數據庫。上述的A和B分別代表數據庫中的User表和Department表。


四、優勢

(1)抽象工廠模式是對工廠方法模式的改進。用於處理產品不只有一類的情況(工廠方法模式下,產品只有User這一類,而抽象工廠模式下,產品包括User和Department兩類)。

(2)在以下情況下應當考慮使用抽象工廠模式

  •  一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有形態的工廠模式都是重要的。
  • 這個系統有多於一個的產品族,而系統只消費其中某一產品族。
  • 同屬於同一個產品族的產品是在一起使用的,這一約束必須在系統的設計中體現出來。
  • 系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於實現。

(3)解讀:

在上例中,產品族包括兩個:1和2,也就是Sqlserver數據庫和Access數據庫。每個產品族裏面又包含兩類產品:A和B,也就是User表和Department表。而每個產品族中的產品要一起使用,就是說產品族1中的兩類產品A和B要一起使用,也就是說在SqlServer數據庫中SqlServerUser表和SqlServerDepartment表要一起使用,Access數據庫同理。

五、C++實現

(1)代碼

#include <iostream>
#include <cstdlib>

using namespace std;


//數據庫表項:User
class User
{
private:
	int id;
	string name;
public:
	int getID()
	{
		return id;
	}
	string getName()
	{
		return name;
	}
	void setID(int ID)
	{
		this->id=ID;
	}
	void setName(string NAME)
	{
		this->name=NAME;
	}
};


//數據庫表項:Department
class Department
{
private:
	int id;
	string name;
public:
	int getID()
	{
		return id;
	}
	string getName()
	{
		return name;
	}
	void setID(int ID)
	{
		this->id=ID;
	}
	void setName(string NAME)
	{
		this->name=NAME;
	}
};



//抽象產品A:IUser
class IUser
{
public:
	virtual void Insert(User user)=0;
	virtual User* GetUser(int id)=0;
};
//具體產品A1:SqlserverUser
class SqlserverUser:public IUser
{
public:
	void Insert(User user)
	{
		cout<<"在SQL Server中給User表增加了一條記錄"<<endl;
	}
	User* GetUser(int id)
	{
		cout<<"在SQL Server中根據ID得到User表一條記錄"<<endl;
		return NULL;
	}
};
//具體產品A2:AccessUser
class AccessUser:public IUser
{
public:
	void Insert(User user)
	{
		cout<<"在Access中給User表增加了一條記錄"<<endl;
	}
	User* GetUser(int id)
	{
		cout<<"在Access中根據ID得到User表一條記錄"<<endl;
		return NULL;
	}
};


//抽象產品B:IDepartment
class IDepartment
{
public:
	virtual void Insert(Department department)=0;
	virtual Department* GetDepartment(int id)=0;
};
//具體產品B1:SqlserverDepartment
class SqlserverDepartment:public IDepartment
{
public:
	void Insert(Department department)
	{
		cout<<"在Sql Server中給Department表添加了一條記錄"<<endl;
	}
	Department* GetDepartment(int id)
	{
		cout<<"在SQL Server中根據ID得到Department表的一條記錄"<<endl;
		return NULL;
	}
};
//具體產品B2:AccessDepartment
class AccessDepartment:public IDepartment
{
public:
	void Insert(Department department)
	{
		cout<<"在Access中給Department表添加了一條記錄"<<endl;
	}
	Department* GetDepartment(int id)
	{
		cout<<"在Access中根據ID得到Department表的一條記錄"<<endl;
		return NULL;
	}
};



//抽象工廠:IFactory
class IFactory
{
public:
	virtual IUser* CreateUser()=0;
	virtual IDepartment* CreateDepartment()=0;
};
//具體工廠1:SqlServerFactory
class SqlserverFactory:public IFactory
{
public:
	IUser* CreateUser()
	{
		return new SqlserverUser;
	}

	IDepartment* CreateDepartment()
	{
		return new SqlserverDepartment;
	}
};
//具體工廠2:AccessFactory
class AccessFactory:public IFactory
{
public:
	IUser* CreateUser()
	{
		return new AccessUser;
	}

	IDepartment* CreateDepartment()
	{
		return new AccessDepartment;
	}
};



//客戶端
void  main()
{
	User user;
	Department department;

	//ConcreteFactory1
	IFactory* factory=NULL;
	factory=new SqlserverFactory;
	
	//ProductA1
	IUser* iu=NULL;
	iu=factory->CreateUser();
	iu->Insert(user);
	iu->GetUser(1);

	//ProductB1
	IDepartment* id=NULL;
	id=factory->CreateDepartment();
	id->Insert(department);
	id->GetDepartment(1);

	if(factory!=NULL)
	{
		delete factory;
		factory=NULL;
	}
	if(iu!=NULL)
	{
		delete iu;
		iu=NULL;
	}
	if(id!=NULL)
	{
		delete id;
		id=NULL;
	}

	system("pause");
}

(2)運行截圖


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章