简单工厂模式的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择动态的实例化相关类,对于客客户端来说是去除了对产品的依赖。但是就是因为这样,每次添加一个新的选择,就要修改工厂类中的switch逻辑分支,这显然违背了开放-封闭原则;
工厂方法模式:
定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类。
工厂方法实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题依然存在,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端进行,如果想要加功能。则是由更改工厂类转变为了更改客户端。
下面引入两个示例来介绍这个模式方法:
1 用工厂方法模式实现计算器功能:
#include <iostream>
using namespace std;
//抽象产品类
class operation
{
protected:
double _num_A;
double _num_B;
public:
double get_A(){
return _num_A;
}
double get_B(){
return _num_B;
}
void set_A(double num)
{
_num_A=num;
}
void set_B(double num)
{
_num_B=num;
}
//基类中将操作实现方法设置为虚函数
virtual double getResult()=0;
virtual ~operation()//当子类含有动态分配的内存时,需要把基类的析构函数声明为虚函数。
// 此处可不用声明为虚函数。因为子类中没有动态分配的内存。此处写出知识为了举例
{
cout<<"base destruction"<<endl;
}
};
//具体产品类
//实现子类继承父类的具体实现
//实现加法功能
class operationAdd:public operation //加法类继承自operation
{
double getResult(){
return _num_A+_num_B;
}
//构造之后进行析构 防止内存泄漏
~operationAdd(){
cout<<"ADD destruction"<<endl;
}
};
//实现减法功能
class operationSub:public operation
{
double getResult(){
return _num_A-_num_B;
}
};
//实现乘法功能
class operationMul:public operation
{
double getResult(){
return _num_A*_num_B;
}
};
//实现除法功能
class operationdiv:public operation
{
double getResult(){
return _num_A/_num_B;
}
};
//工厂方法类
class factory//先构建一个工厂接口
{
public:
virtual operation* createOperation()=0; //纯虚函数
};
class addFactory:public factory
{
public:
operation* createOperation(){
return new operationAdd();
}
};
class subFactory:public factory
{
public:
operation* createOperation(){
return new operationSub();
}
};
class mulFactory:public factory
{
public:
operation* createOperation(){
return new operationMul();
}
};
class divFactory:public factory
{
public:
operation* createOperation(){
return new operationdiv();
}
};
//主界面函数体
int main()
{
factory* operfactory=new addFactory();
operation* add=operfactory->createOperation();
add->set_A(1);
add->set_B(1);
cout<<add->getResult();
return 0;
}
在这里插入代码片
2 工厂方法模式实现雷锋功能:
#include <iostream>
#include <string>
using namespace std;
class leifeng
{
public:
void saodi(){
cout<<"扫地 ";
}
void maifan(){
cout<<"买饭 ";
}
};
class daxuesheng:public leifeng
{
};
class shehuizhiyuanzhe:public leifeng
{
};
//雷锋工厂实现
class leifengfactory
{
public:
virtual leifeng* CreateLeiFeng()=0;
};
//大学生工厂实现
class daxueshengFactory:public leifengfactory
{
public:
leifeng* CreateLeiFeng(){
cout<<"大学生雷锋";
return new daxuesheng;
}
};
class shehuizhiyuanzheFactory:public leifengfactory
{
public:
leifeng* CreateLeiFeng(){
return new shehuizhiyuanzhe;
}
};
int main(){
leifengfactory* lff=new daxueshengFactory;//父类指针指向子类对象 返回一个子类new出来的对象
leifeng* xiaoli=lff->CreateLeiFeng();//创建雷锋类对象接收雷锋工厂对象调用子类函数的结果
xiaoli->saodi();//实现雷锋对象的具体功能
return 0;
}
在这里插入代码片
抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口,而不需指定他们具体的类;
抽象工厂模式的优缺点
好处便是易于交换产品系列,有与具体工厂类,在一个应用中只需要初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。
它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口曹忠实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
引入一个抽象工厂模式的示例:
#include <iostream>
#include <string>
using namespace std;
//抽象工厂实现数据库访问。有两个数据库 sqlUser accessUser,每个数据库有两个表项sqldepartment accessdepartment
class IUser
{
public:
virtual void setuser()=0;//设置用户
virtual void getuser()=0;//获取用户
};
class sqlUser:public IUser
{
public:
virtual void setuser()
{
cout<<"在SQL Server中给User增加一条记录"<<endl;
}
virtual void getuser()
{
cout<<"在SQL Server中根据ID得到User一条记录"<<endl;
}
};
class AccessUser:public IUser
{
public:
virtual void setuser()
{
cout<<"在Acess Server中给User增加一条记录"<<endl;
}
virtual void getuser()
{
cout<<"在Acess Server中根据ID得到User一条记录"<<endl;
}
};
class IDepartment
{
public:
virtual void getDepartment()=0;
virtual void setDepartment()=0;
};
class SqlDepartment:public IDepartment
{
public:
void getDepartment()
{
cout<<"在Sql Server中根据ID得到Department一条记录"<<endl;
}
void setDepartment()
{
cout<<"在Sql Server中给Department增加一条记录"<<endl;
}
};
class AccessDepartment:public IDepartment
{
public:
void getDepartment()
{
cout<<"在Acess Server中根据ID得到Department一条记录"<<endl;
}
void setDepartment()
{
cout<<"在Acess Server中给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();
}
};
int main()
{
IFactory* sql=new SqlFactory;
IUser * user=sql->createUser();
IDepartment* department=sql->createDepartment();
user->setuser();
user->getuser();
department->setDepartment();
department->getDepartment();
return 0;
}
在这里插入代码片
用简单工厂模式重写上面例子:
#include <iostream>
#include <string>
using namespace std;
//抽象工厂实现
//用户父类IUer 它有俩子类 即对应两个数据库
class IUser
{
public:
virtual void setuser()=0;
virtual void getuser()=0;
};
//用户子类sqlUser
class sqlUser:public IUser
{
public:
virtual void setuser()
{
cout<<"在SQL Server中给User增加一条记录"<<endl;
}
virtual void getuser()
{
cout<<"在SQL Server中根据ID得到User一条记录"<<endl;
}
};
//子类用户AccessUser
class AccessUser:public IUser
{
public:
virtual void setuser()
{
cout<<"在Acess Server中给User增加一条记录"<<endl;
}
virtual void getuser()
{
cout<<"在Acess Server中根据ID得到User一条记录"<<endl;
}
};
//表项父类
class IDepartment
{
public:
virtual void getDepartment()=0;
virtual void setDepartment()=0;
};
//表项子类SqlDepartment
class SqlDepartment:public IDepartment
{
public:
void getDepartment()
{
cout<<"在Sql Server中根据ID得到Department一条记录"<<endl;
}
void setDepartment()
{
cout<<"在Sql Server中给Department增加一条记录"<<endl;
}
};
//表项子类 AccessDepartment
class AccessDepartment:public IDepartment
{
public:
void getDepartment()
{
cout<<"在Acess Server中根据ID得到Department一条记录"<<endl;
}
void setDepartment()
{
cout<<"在Acess Server中给Department增加一条记录"<<endl;
}
};
//获取数据
class Accessdata
{
public:
static string db;
static IUser* createUser(){
if(db=="sql")
return new sqlUser;
else if(db=="access")
return new AccessUser;
}
static IDepartment* createDepartment(){
if(db=="sql")
return new SqlDepartment;
else if(db=="access")
return new AccessDepartment;
}
};
string Accessdata::db="sql"; //作用域
int main()
{
Accessdata DB;
IUser * user=DB.createUser(); //获取数据库
IDepartment* department=DB.createDepartment();//获取表项
user->setuser();
user->getuser();
department->setDepartment();
department->getDepartment();
return 0;
}
在这里插入代码片