设计模式之 工厂方法模式&&抽象工厂模式

在这里插入图片描述
简单工厂模式的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择动态的实例化相关类,对于客客户端来说是去除了对产品的依赖。但是就是因为这样,每次添加一个新的选择,就要修改工厂类中的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;

}
在这里插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.liang呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值