专业编程基础技术教程

网站首页 > 基础教程 正文

设计模式之工厂模式

ccvgpt 2024-08-16 15:05:19 基础教程 9 ℃

概念和介绍

工厂设计模式定义了创建对象的接口,允许子类决定实例化哪个类,而且允许请求者无须知道要被实例化的特定类,这样可以在不修改代码的情况下引入新类。

工厂设计模式优点:

设计模式之工厂模式

(1)没有了将应用程序类绑定到代码中的要求,可以使用任何实现了接口的类

(2) 允许子类提供对象的扩展版本。

工厂设计模式的应用场景:

(1)类不能预料它必须创建的对象的类;

(2)类希望其子类指定它要创建的对象。

场景举例:

应用程序设计中,数据库访问需要良好的封装性和可维护性,因此经常使用工厂设计模式来实现对数据库访问的封装。

在数据访问层定义采用工厂模式,定义统一的操纵数据库的接口,然后根据数据库的不同,由类工厂来决定实例化哪个类。在具体类中实现特定的数据库访问类。这样,就可以实现由客户端指定或根据配置文件来选择访问不同的数据库,从而实现应用程序与数据库无关。


分类

工厂设计模式主要有如下几种:

一、简单工厂(Simple Factory)模式

代码实现:根据输入,返回创建的对象。通常只有一个工厂类

使用一个专门的工厂负责生产对象,这个工厂类定义一个用于创建产品的静态接口,直接通过调用工厂类那个方法的方式获取需要的对象。可以定义不同的接口生产不同的对象,也可以定义一个接口通过函数参数生成不同对象。简单工厂生产的产品是统一的抽象产品,方便外部调用者可以提供通用的处理方式。一个工厂类来统一负责所有产品的创建。

优点:新添加类时,不会影响以前的系统代码。适用于不同情况创建不同的类时。

缺点:客户端必须要知道基类和工厂类,耦合性差。


示例代码和类图:

#include <string>
#include <iostream>
using namespace std;

//基类
class COperation
{
public:
    int m_nFirst;
    int m_nSecond;
    virtual double GetResult()
    {
        double dResult=0;
        return dResult;
    }
};
//加法
class AddOperation : public COperation
{
public:
    virtual double GetResult()
    {
        return m_nFirst+m_nSecond;
    }
};
//减法
class SubOperation : public COperation
{
public:
    virtual double GetResult()
    {
        return m_nFirst-m_nSecond;
    }
};

//工厂类
class CCalculatorFactory
{
public:
    static COperation* Create(char cOperator);
};
COperation* CCalculatorFactory::Create(char cOperator)
{
    COperation *oper;

    switch (cOperator)
    {
    case '+':
        oper=new AddOperation();
        break;
    case '-':
        oper=new SubOperation();
        break;
    default:
        oper=new AddOperation();
        break;
    }
    return oper;
}

//客户端
int main()
{
    int a,b;
    cin>>a>>b;
    COperation * op=CCalculatorFactory::Create('-');
    op->m_nFirst=a;
    op->m_nSecond=b;
    cout<<op->GetResult()<<endl;
    return 0;
}


二、工厂方法(Factory Method)模式

代码实现:一个工厂方法接口,有多个工厂类实现这个接口,最终由调用者通过工厂类创建对象。

更进一步:可以创建一个管理工厂类的工厂或者工具,方便使用者调用。

相比简单工厂只是讲产品抽象,工厂方法模式将工厂也抽象化了不同的产品由不同的具体工厂负责生产

优点:

修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可

示例代码和类图:

#include <string>
#include <iostream>
using namespace std;

//实例基类,相当于 Product
class LeiFeng
{
public:
    virtual void Sweep()
    {
        cout << "雷锋扫地" << endl;
    }
};
//学雷锋的大学生,相当于 ConcreteProduct
class Student : public LeiFeng
{
public:
    virtual void Sweep()
    {
        cout << "大学生扫地" << endl;
    }
};
//学雷锋的志愿者,相当于 ConcreteProduct
class Volenter : public LeiFeng
{
public:
    virtual void Sweep()
    {
        cout << "志愿者扫地" << endl;
    }
};

//工场基类 Creator
class LeiFengFactory
{
public:
    virtual LeiFeng* CreateLeiFeng()
    {
        return new LeiFeng();
    }
};
//工场具体类
class StudentFactory : public LeiFengFactory
{
public:
    virtual LeiFeng* CreateLeiFeng()
    {
        return new Student();
    }
};
class VolenterFactory : public LeiFengFactory {
public:
    virtual LeiFeng* CreateLeiFeng()
    {
        return new Volenter();
    }
};
//客户端
int main()
{
    LeiFengFactory* sf = new LeiFengFactory();
    LeiFeng* s = sf->CreateLeiFeng();
    s->Sweep();
    delete s;
    delete sf;
    return 0;
}


三、抽象工厂(Abstract Factory)模式

代码实现:一个接口文件中有多个接口(方法),每一个工厂类中也需要实现多个接口

提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品

工厂方法模式只能生产一类产品,而实际开发中我们需要的可能是一系列关联的产品对象,这就用到了抽象工厂模式。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

优点:

1.用户只需要知道具体工厂的名称就可得到所要的产品, 无须知道产品的具体创建过程;

2.灵活性增强, 对于新产品的创建,只需多写一个相应的工厂类。

应用场景:

用于交换产品系列,如,可以针对 Oracle、 MySQL、 DB2 等分别建立抽象工厂, 这样便于数据库之间的切换。

示例代码和类图:

#include <string>
#include <iostream>
#include <vector>
using namespace std;
//用户抽象接口
class IUser
{
public:
    virtual void GetUser() = 0;
    virtual void InsertUser() = 0;
};
//部门抽象接口
class IDepartment
{
public:
    virtual void GetDepartment() = 0;
    virtual void InsertDepartment() = 0;
};
//ACCESS 用户
class CAccessUser : public IUser
{
public:
    virtual void GetUser()
    {
        cout << "Access GetUser" << endl;
    }
    virtual void InsertUser()
    {
        cout << "Access InsertUser" << endl;
    }
};
//ACCESS 部门
class CAccessDepartment : public IDepartment
{
public:
    virtual void GetDepartment()
    {
        cout << "Access GetDepartment" << endl;
    }
    virtual void InsertDepartment()
    {
        cout << "Access InsertDepartment" << endl;
    }
};

//SQL 用户
class CSqlUser : public IUser
{
public:
    virtual void GetUser()
    {
        cout << "Sql User" << endl;
    }
    virtual void InsertUser()
    {
        cout << "Sql User" << endl;
    }
};

//SQL 部门类
class CSqlDepartment : public IDepartment
{
public:
    virtual void GetDepartment()
    {
        cout << "sql getDepartment" << endl;
    }
    virtual void InsertDepartment()
    {
        cout << "sql insertdepartment" << endl;
    }
};

//抽象工厂
class IFactory
{
public:
    virtual IUser* CreateUser() = 0;
    virtual IDepartment* CreateDepartment() = 0;
};

//ACCESS 工厂
class AccessFactory : public IFactory
{
public:
    virtual IUser* CreateUser()
    {
        return new CAccessUser();
    }
    virtual IDepartment* CreateDepartment()
    {
        return new CAccessDepartment();
    }
};
//SQL 工厂
class SqlFactory : public IFactory
{
public:
    virtual IUser* CreateUser()
    {
        return new CSqlUser();
    }
    virtual IDepartment* CreateDepartment()
    {
        return new CSqlDepartment();
    }
};

//客户端:
int main()
{
    IFactory* factory = new SqlFactory();
    IUser* user = factory-> CreateUser();
    IDepartment* depart = factory-> CreateDepartment();
    user-> GetUser();
    depart-> GetDepartment();
        return 0;
}

最近发表
标签列表