鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

大话设计模式:抽象工厂模式

来源:互联网 作者:佚名 时间:2016-07-17 21:15
抽象方法模式: 提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。 三种模式的对比: 简单工厂模式 工厂模式 抽象工厂模式 产品 可以有多个但是都属于同一类, 同一等级。都继承产品抽象类。 可以有多个但是都属于同一类,同一等级。
抽象方法模式:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
三种模式的对比:
  简单工厂模式 工厂模式 抽象工厂模式
产品 可以有多个但是都属于同一类,
同一等级。都继承产品抽象类。
可以有多个但是都属于同一类,同一等级。
都继承产品抽象类。
可以有不同种类的产品,每类有多中
具体产品;
抽象产品 只能有一个 只能有一个; 多个抽象产品类;每个抽象产品类可
以派生多种具体产品;
抽象工厂类   只能有一个,可以派生出多个具体工厂类; 只有一个,可派生出多个具体工厂类;
具体工厂 制造不同的产品,直接实例化
产品对象;
一个具体工厂类只能创建一个具体的产品; 可以创建多个具体产品类的实例;








以书上的数据库访问为例:
抽象工厂中的角色有:
(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;
}  
运行结果:

  小结:如果产品单一,要想达到以上的效果,合适用工厂模式;但是如果有多个品种分级时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。可以根据实际情况进行选择。



网友评论
<