抽象工厂模式:提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体的类。它用于解决涉及多个产品系列的问题,包含所有产品的创建方法。
AbstractProductA和AbstractProductB是两个抽象的产品,之所以称之为抽象就是因为它们可以有两种不同的实现,ProductaA1,ProductA2,和ProductB1,ProductB2就是他它们的具体实现。就像代码中的User和Department表,派生了AccessUser和AccessDepartment以及SQLUser和SQLDeparment。
IFactory是抽象工厂接口,它包含所有产品创建方法的抽象方法。ConcretFactory1和ConcreteFactory2就是具体的抽象工厂。就像AccessFactory和SQLFactroy。
#include<iostream>
using namespace std;
class User
{
public:
User()
{
}
virtual void insert()=0;
virtual void get()=0;
};
class AccessUser:public User
{
public:
AccessUser()
{
}
virtual void insert()
{
cout<<"AccessUser Insert a new record in the User table!!"<<endl;
}
virtual void get()
{
cout<<"AccessUser get a record n the User table!"<<endl;
}
};
class SQLUser:public User
{
public:
SQLUser()
{
}
virtual void insert()
{
cout<<"SQLSERVER Insert a new record in the User table!!"<<endl;
}
virtual void get()
{
cout<<"SQLSERVER get a record in the User table!"<<endl;
}
};
class Department
{
public:
Department()
{
}
virtual void insert()=0;
virtual void get()=0;
};
class AccessDepartment:public Department
{
public:
AccessDepartment()
{
}
virtual void insert()
{
cout<<"Access Insert a new record in the Department table"<<endl;
}
virtual void get()
{
cout<<"Access get a new record in the Department table"<<endl;
}
};
class SQLDepartment:public Department
{
public:
SQLDepartment()
{
}
virtual void insert()
{
cout<<"SQL server Insert a new record in the Department table"<<endl;
}
virtual void get()
{
cout<<"SQL server get a new record in the Department table"<<endl;
}
};
class IFactroy
{
public:
IFactroy()
{
}
virtual User*CreateUser()=0;
virtual Department*CreateDepartment()=0;
};
class AccessFactory:public IFactroy
{
public:
AccessFactory()
{
}
virtual User*CreateUser()
{
return new AccessUser();
}
virtual Department*CreateDepartment()
{
return new AccessDepartment;
}
};
class SQLFactory:public IFactroy
{
public:
SQLFactory()
{
}
virtual User*CreateUser()
{
return new SQLUser();
}
virtual Department*CreateDepartment()
{
return new SQLDepartment;
}
};
int main(int argc,char**argv)
{
IFactroy *factory=new SQLFactory;
User *user=factory->CreateUser();
user->insert();
user->get();
Department*dp=factory->CreateDepartment();
dp->insert();
dp->get();
factory=new AccessFactory;
user=factory->CreateUser();
dp=factory->CreateDepartment();
user->get();
user->insert();
dp->get();
dp->insert();
cout<<"简单工厂模式改进!"<<endl;
DataAccess da(2);
user=da.createUser();
dp=da.createDepartment();
user->get();
user->insert();
dp->get();
dp->insert();
DataAccess da2(1);
user=da2.createUser();
dp=da2.createDepartment();
user->get();
user->insert();
dp->get();
dp->insert();
return 0;
}
通常在运行时创建具体的工厂,根据这个工厂在创建不同的产品对象。
抽象工厂的好处是,一:易于更换产品,由于具体的工厂如IFactory*factory=newAccessFactory;仅仅在初始化的时候出现一次,就使得改变具体的抽象工厂非常容易。二:让具体的实例创建过程与客户端分离,客户端通过抽象接口操纵实例,产品的具体类也被具体模式的实现分离,不会出现在客户代码中。
缺点:抽象工厂可以很方便的切换两个数据库,但是当需求增加时如需要增加Project表时就需要改动三个类,即IFactory,AccessFactory,SQLFacroy另外还得增加三个类。还有,访问数据库的客户端代码很可能有多处,更换数据库时需要修改每一处,这仍然很不方便。编程是一门艺术,这样大批量的改动显然是丑陋的做法。
使用简单工厂改进抽象工厂
class DataAccess
{
public:
int type;
public:
DataAccess(int t)
{
type=t;
}
User*createUser()
{
switch(type)
{
case 1:
{
return new AccessUser;
}
break;
case 2:
{
return new SQLUser;
}
break;
default:
break;
}
}
Department*createDepartment()
{
switch(type)
{
case 1:
{
return new AccessDepartment;
}
break;
case 2:
{
return new SQLDepartment;
}
break;
default:
break;
}
}
};
int main(int argc,char**argv)
{
IFactroy *factory=new SQLFactory;
User *user=factory->CreateUser();
user->insert();
user->get();
Department*dp=factor->CreateDepartment();
cout<<"简单工厂模式改进!"<<endl;
DataAccess da(2);
user=da.createUser();
dp=da.createDepartment();
user->get();
user->insert();
dp->get();
dp->insert();
DataAccess da2(1);
user=da2.createUser();
dp=da2.createDepartment();
user->get();
user->insert();
dp->get();
dp->insert();
return 0;
}