抽象工厂模式(Abstract Factory): 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。
通常是在运行时刻在创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class User {};
class Department {};
class IUser
{
public:
virtual void Insert(User* user) = 0;
virtual User* GetUser(int id) = 0;
};
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 nullptr;
}
};
class AccessUser :public IUser
{
public:
void Insert(User* user)
{
cout << "在Access中给User表增加一条记录" << endl;
}
User* GetUser(int id)
{
cout << "在Access中根据ID得到User表一条记录" << endl;
return nullptr;
}
};
class IDepartment
{
public:
virtual void Insert(Department* department) = 0;
virtual Department* GetDeparment(int id) = 0;
};
class SqlserverDepartment :public IDepartment
{
public:
void Insert(Department* department)
{
cout << "在SQL Server中给Department表增加一条记录" << endl;
}
Department* GetDeparment(int id)
{
cout << "在SQL Server中根据ID得到Department表一条记录" << endl;
return nullptr;
}
};
class AccessDepartment :public IDepartment
{
public:
void Insert(Department* department)
{
cout << "在Access中给Department表增加一条记录" << endl;
}
Department* GetDeparment(int id)
{
cout << "在Access中根据ID得到Department表一条记录" << endl;
return nullptr;
}
};
class IFactory
{
public:
virtual IUser* CreateUser() = 0;
virtual IDepartment* CreateDepartment() = 0;
};
class SqlServerFactory :public IFactory
{
public:
IUser* CreateUser()
{
return new SqlserverUser();
}
IDepartment* CreateDepartment()
{
return new SqlserverDepartment();
}
};
class AccessFactory : public IFactory
{
public:
IUser* CreateUser()
{
return new AccessUser();
}
IDepartment* CreateDepartment()
{
return new AccessDepartment();
}
};
int main()
{
User* user = new User();
Department* dept = new Department();
IFactory* factory = new SqlServerFactory();
IUser* iu = factory->CreateUser();
iu->Insert(user);
iu->GetUser(1);
IDepartment* id = factory->CreateDepartment();
id->Insert(dept);
id->GetDeparment(1);
system("pause");
return 0;
}
- 优点:一是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。再一点是它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
- 缺点: 当需要增加需求是,比如添加一个Oracle数据库是,需要进行大批量的改动。
用简单工厂来改进抽象工厂
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class User {};
class Department {};
class IUser
{
public:
virtual void Insert(User* user) = 0;
virtual User* GetUser(int id) = 0;
};
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 nullptr;
}
};
class AccessUser :public IUser
{
public:
void Insert(User* user)
{
cout << "在Access中给User表增加一条记录" << endl;
}
User* GetUser(int id)
{
cout << "在Access中根据ID得到User表一条记录" << endl;
return nullptr;
}
};
class IDepartment
{
public:
virtual void Insert(Department* department) = 0;
virtual Department* GetDeparment(int id) = 0;
};
class SqlserverDepartment :public IDepartment
{
public:
void Insert(Department* department)
{
cout << "在SQL Server中给Department表增加一条记录" << endl;
}
Department* GetDeparment(int id)
{
cout << "在SQL Server中根据ID得到Department表一条记录" << endl;
return nullptr;
}
};
class AccessDepartment :public IDepartment
{
public:
void Insert(Department* department)
{
cout << "在Access中给Department表增加一条记录" << endl;
}
Department* GetDeparment(int id)
{
cout << "在Access中根据ID得到Department表一条记录" << endl;
return nullptr;
}
};
class DataAccess
{
private:
static const string db;
public:
static IUser* CreateUser()
{
IUser* result = nullptr;
if (db == "Sqlserver")
{
result = new SqlserverUser();
}
else if (db == "Access")
{
result = new AccessUser();
}
return result;
}
static IDepartment* CreateDepartment()
{
IDepartment* result = nullptr;
if (db == "Sqlserver")
{
result = new SqlserverDepartment();
}
else if (db == "Access")
{
result = new AccessDepartment();
}
return result;
}
};
const string DataAccess::db = "Sqlserver";
int main()
{
User* user = new User();
Department* dept = new Department();
IUser* iu = DataAccess::CreateUser();
iu->Insert(user);
iu->GetUser(1);
IDepartment* id = DataAccess::CreateDepartment();
id->Insert(dept);
id->GetDeparment(1);
system("pause");
return 0;
}
用反射+抽象工厂
.......................