大話設計模式:抽象工廠模式
抽象方法模式:提供一個建立一系列相關或互相依賴物件的介面,而無需指定他們具體的類。
三種模式的對比:
抽象工廠中的角色有:
(1)抽象工廠:只能一個(IFactory)
(2)具體工廠: 包括具體工廠1:SqlServerFactory和具體工廠2:AccessFactory。
具體工廠1用於生產具體產品A1:SqlserverUser和具體產品B1:SqlserverDepartment,
具體工廠2用於生產具體產品A2:AccessUser和B2;AccessDepartment,
(3)抽象產品: 包括抽象產品A:IUser和抽象產品B:IDepartment;
(4)具體產品:包括抽象產品A所對應的具體產品A1和A2,以及抽象產品B所對應的具體產品B1和B2.
優點:
(1)抽象工廠模式是對工廠方法模式的改進,可以處理多類的產品,不侷限與某一類,因為有多個抽象產品類。例如此例如果在工廠方法模式下,產品只有User或者Department其中的一類,而抽象工廠模式下,產品包括User和Department兩類)
(2)易於交換產品系列,例如我們在選擇資料庫時,只需要初始化一次AccessFactory或者SqlServerFactory,就可以使用不同資料庫的配置,使之使用非常靈活。另外它使建立例項的過程與客戶端分離。很好的符合了開放-封閉原則和依賴倒轉原則。
缺點:如果要增加一個新的功能,需要改動的地方太多。
例如如果我們要增加一個新的專案表Project,那麼我的增加至少三個類:IProject,SqlserverProject、AccessProject,還需要更改抽象類IFactory、SqlserverFactory和AccessFactory才可以實現,這是非常多的。
其UML圖如下:
具體實現程式碼如下:
小結:如果產品單一,要想達到以上的效果,合適用工廠模式;但是如果有多個品種分級時,通過抽象工廠模式產生需要的物件是一種非常好的解決方式。可以根據實際情況進行選擇。
三種模式的對比:
簡單工廠模式 | 工廠模式 | 抽象工廠模式 | |
產品 | 可以有多個但是都屬於同一類, 同一等級。都繼承產品抽象類。 |
可以有多個但是都屬於同一類,同一等級。 都繼承產品抽象類。 |
可以有不同種類的產品,每類有多中 具體產品; |
抽象產品 | 只能有一個 | 只能有一個; | 多個抽象產品類;每個抽象產品類可 以派生多種具體產品; |
抽象工廠類 | 只能有一個,可以派生出多個具體工廠類; | 只有一個,可派生出多個具體工廠類; | |
具體工廠 | 製造不同的產品,直接例項化 產品物件; |
一個具體工廠類只能建立一個具體的產品; | 可以建立多個具體產品類的例項; |
抽象工廠中的角色有:
(1)抽象工廠:只能一個(IFactory)
(2)具體工廠: 包括具體工廠1:SqlServerFactory和具體工廠2:AccessFactory。
具體工廠1用於生產具體產品A1:SqlserverUser和具體產品B1:SqlserverDepartment,
具體工廠2用於生產具體產品A2:AccessUser和B2;AccessDepartment,
(3)抽象產品: 包括抽象產品A:IUser和抽象產品B:IDepartment;
(4)具體產品:包括抽象產品A所對應的具體產品A1和A2,以及抽象產品B所對應的具體產品B1和B2.
優點:
(1)抽象工廠模式是對工廠方法模式的改進,可以處理多類的產品,不侷限與某一類,因為有多個抽象產品類。例如此例如果在工廠方法模式下,產品只有User或者Department其中的一類,而抽象工廠模式下,產品包括User和Department兩類)
(2)易於交換產品系列,例如我們在選擇資料庫時,只需要初始化一次AccessFactory或者SqlServerFactory,就可以使用不同資料庫的配置,使之使用非常靈活。另外它使建立例項的過程與客戶端分離。很好的符合了開放-封閉原則和依賴倒轉原則。
缺點:如果要增加一個新的功能,需要改動的地方太多。
例如如果我們要增加一個新的專案表Project,那麼我的增加至少三個類:IProject,SqlserverProject、AccessProject,還需要更改抽象類IFactory、SqlserverFactory和AccessFactory才可以實現,這是非常多的。
其UML圖如下:
具體實現程式碼如下:
#include <iostream>
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;
}
};
//客戶端
int 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");
return 0;
}
執行結果:小結:如果產品單一,要想達到以上的效果,合適用工廠模式;但是如果有多個品種分級時,通過抽象工廠模式產生需要的物件是一種非常好的解決方式。可以根據實際情況進行選擇。
相關文章
- 大話設計模式:工廠模式設計模式
- 設計模式——抽象工廠模式設計模式抽象
- 設計模式 —— 抽象工廠模式設計模式抽象
- 設計模式-抽象工廠模式設計模式抽象
- 設計模式之工廠方法模式|抽象工廠模式設計模式抽象
- 【大話設計模式】—— 工廠方法模式設計模式
- 設計模式-簡單工廠、工廠方法模式、抽象工廠模式設計模式抽象
- 設計模式----抽象工廠設計模式抽象
- 設計模式 – 抽象工廠設計模式抽象
- 設計模式 - 抽象工廠設計模式抽象
- java設計模式–抽象工廠模式Java設計模式抽象
- Java設計模式-抽象工廠模式Java設計模式抽象
- 設計模式系列·抽象工廠模式設計模式抽象
- 設計模式(十三)抽象工廠模式設計模式抽象
- 設計模式(四)——抽象工廠模式設計模式抽象
- 設計模式學習(二)工廠模式——抽象工廠模式設計模式抽象
- 大話設計模式:簡單工廠模式設計模式
- 【大話設計模式】——簡單工廠模式設計模式
- C# 設計模式(1)——簡單工廠模式、工廠模式、抽象工廠模式C#設計模式抽象
- Java 設計模式之工廠方法模式與抽象工廠模式Java設計模式抽象
- golang設計模式之抽象工廠模式Golang設計模式抽象
- 設計模式系列之「抽象工廠模式」設計模式抽象
- 設計模式(三)抽象工廠方法模式設計模式抽象
- 建立型設計模式——抽象工廠模式設計模式抽象
- 23種設計模式(抽象工廠模式)設計模式抽象
- python設計模式-抽象工廠模式Python設計模式抽象
- C# 設計模式----抽象工廠模式C#設計模式抽象
- 無廢話設計模式(1)--簡單工廠、工廠方法、抽象工廠設計模式抽象
- 【設計模式之抽象工廠】設計模式抽象
- 設計模式(三):抽象工廠設計模式抽象
- 設計模式之工廠模式!深入解析簡單工廠模式,工廠方法模式和抽象工廠模式設計模式抽象
- 設計模式學習(六)-抽象工廠模式設計模式抽象
- 設計模式--抽象工廠模式(Abstract Factory Pattern)設計模式抽象
- Java常用設計模式之抽象工廠模式Java設計模式抽象
- 設計模式(五)抽象工廠模式詳解設計模式抽象
- 23種設計模式之抽象工廠模式設計模式抽象
- C#設計模式(4)——抽象工廠模式C#設計模式抽象
- 設計模式-抽象工廠模式(Abstract Factory Pattern)設計模式抽象