設計模式之抽象工廠模式

抽象工廠模式

 

1. 抽象工廠模式:

爲創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類。

2. 抽象工廠模式與工廠方法模式:

抽象工廠模式是工廠方法模式的升級版本,用來創建一組相關或者相互依賴的對象。他與工廠方法模式的區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對的多個產品等級結構。在編程中,通常一個產品結構,表現爲一個接口或者抽象類,也就是說,工廠方法模式提供的所有產品都是衍生自同一個接口或抽象類而抽象工廠模式所提供的產品則是衍生自不同的接口或抽象類。

在抽象工廠模式中,有一個產品族的概念:所謂的產品族,是指位於不同產品等級結構中功能相關聯的產品組成的家族。抽象工廠模式所提供的一系列產品就組成一個產品族;而工廠方法提供的一系列產品稱爲一個等級結構。

3. 抽象工廠模式的例子:

我們依然拿生產汽車的例子來說明他們之間的區別。.


在本例中,如果一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那麼他屬於工廠方法模式;如果一個工廠模式是提供2.4排量兩廂車和2.4排量三廂車兩個產品,那麼這個工廠模式就是抽象工廠模式,因爲他提供的產品是分屬兩個不同的等級結構。當然,如果一個工廠提供全部四種車型的產品,因爲產品分屬兩個等級結構,他當然也屬於抽象工廠模式了。

抽象工廠模式的優點

        抽象工廠模式除了具有工廠方法模式的優點外,最主要的優點就是可以在類的內部對產品族進行約束。所謂的產品族,一般或多或少的都存在一定的關聯,抽象工廠模式就可以在類內部對產品族的關聯關係進行定義和描述,而不必專門引入一個新的類來進行管理。

抽象工廠模式的缺點

       產品族的擴展將是一件十分費力的事情,假如產品族中需要增加一個新的產品,則幾乎所有的工廠類都需要進行修改。所以使用抽象工廠模式時,對產品等級結構的劃分是非常重要的。

適用場景

就是一個繼承體系中,如果存在着多個等級結構(即存在着多個抽象類),並且分屬各個等級結構中的實現類之間存在着一定的關聯或者約束,就可以使用抽象工廠模式。假如各個等級結構中的實現類之間不存在關聯或約束,則使用多個獨立的工廠來對產品進行創建,則更合適一點。

4. 代碼實例:

class IUser//用戶
{
public:
	virtual void getUser()=0;
	virtual void setUser()=0;
};

class SqlUser:public IUser
{
public:
	void getUser()
	{
		cout<<"在sql中返回user"<<endl;
	}
	void setUser()
	{
		cout<<"在sql中設置user"<<endl;
	}
};

class AccessUser:public IUser
{
public:
	void getUser()
	{
		cout<<"在Access中返回user"<<endl;
	}
	void setUser()
	{
		cout<<"在Access中設置user"<<endl;
	}
};

class IDepartment//部門
{
public:
	virtual void getDepartment()=0;
	virtual void setDepartment()=0;
};

class SqlDepartment:public IDepartment
{
public:
	void getDepartment()
	{
		cout<<"在sql中返回Department"<<endl;
	}
	void setDepartment()
	{
		cout<<"在sql中設置Department"<<endl;
	}
};

class AccessDepartment:public IDepartment
{
public:
	void getDepartment()
	{
		cout<<"在Access中返回Department"<<endl;
	}
	void setDepartment()
	{
		cout<<"在Access中設置Department"<<endl;
	}
};

class IFactory
{
public:
	virtual IUser *createUser()=0;
	virtual IDepartment *createDepartment()=0;
};

class SqlFactory:public IFactory
{
public:
	IUser *createUser() 
	{
		return new SqlUser();
	}
	IDepartment *createDepartment() 
	{
		return new SqlDepartment();
	}
};

class AccessFactory:public IFactory
{
public:
	IUser *createUser()
	{
		return new AccessUser();
	}
	IDepartment *createDepartment() 
	{
		return new AccessDepartment();
	}
};

/*************************************************************/
class DataAccess//去除IFactory、AccessFactory、SqlFactory三個類,用DataAccess類取而代之
{//用一個簡單簡單工廠模式來實現
private:
	static string db;
	//string db="access";
public:
	static IUser *createUser()
	{
		if(db=="access")
		{
			return new AccessUser();
		}
		else if(db=="sql")
		{
			return new SqlUser();
		}
	}
	static IDepartment *createDepartment()
	{
		if(db=="access")
		{
			return new AccessDepartment();
		}
		else if(db=="sql")
		{
			return new SqlDepartment();
		}	
	}
};
string DataAccess::db="sql";

/*************************************************************/
int main()
{
	//IFactory *factory=new SqlFactory();
	IFactory *factory;
	IUser *user;
	IDepartment *department;

	factory=new AccessFactory();
	user=factory->createUser();
	department=factory->createDepartment();
	
	user->getUser();
	user->setUser();
	department->getDepartment();
	department->setDepartment();
	/////////////////////////////
	user=DataAccess::createUser();
	department=DataAccess::createDepartment();

	user->getUser();
	user->setUser();
	department->getDepartment();
	department->setDepartment();

	return 0;
}


發佈了10 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章