【设计模式】——抽象工厂模式

抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

  AbstractProductA和AbstractProductB是两个抽象产品,之所以抽象,是因为他们都有可能有两种不同的实现,而ProductA1、ProductA2和ProductB1、ProductB2就是对两个抽象产品的具体分类的实现。AbstractFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法,而ConcreteFactroy1和ConcreteFactory2就是具体工厂了。通常是在运行时刻在创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端使用不同的具体工厂。

  来看个例子吧,代码结构图如下所示:

#include <iostream>

using namespace std;
//用户类
class User
{
private:
    int _id;
    string _name;
private:
    void SetId(int id)
    {
        this->_id=id;
    }
    int GetId()
    {
        return this->_id;
    }
    void SetName(string name)
    {
        this->_name=name;
    }
    string GetName()
    {
        return this->_name;
    }
};
//IUser接口,用于客户端访问,解除与具体数据访问的耦合
class IUser
{
public:
    virtual void Insert(){}
    virtual void GetUser(){}
};
//SqlserverUser类,用于访问SQL Server的User
class SqlserverUser:public IUser
{
public:
    void Insert()
    {
        cout << "在SQL Server中给user表增加一条记录" << endl;
    }
    void GetUser()
    {
        cout << "在SQL Server中根据ID得到User表一条记录" << endl;
    }
};
//AccessUser类,用于访问Access的User
class AccessUser:public IUser
{
public:
    void Insert()
    {
        cout << "在SQL Server中给user表增加一条记录" << endl;
    }
    void GetUser()
    {
        cout << "在SQL Server中根据ID得到User表一条记录" << endl;
    }
};
//部门类
class Department
{
private:
    int _id;
    string _deptname;
private:
    void SetId(int id)
    {
        this->_id=id;
    }
    int GetId()
    {
        return this->_id;
    }
    void SetDeptname(string name)
    {
        this->_deptname=name;
    }
    string GetName()
    {
        return this->_deptname;
    }
};
//IDpedartment接口,用于客户端访问,解除与具体数据访问的耦合
class IDepartment
{
public:
    virtual void Insert(){}
    virtual void GetUser(){}
};
//SqlserverDepartment类,用于访问SQL Server的Department
class SqlserverDepartment:public IDepartment
{
public:
    void Insert()
    {
        cout << "在SQL Server中给Department表增加一条记录" << endl;
    }
    void GetUser()
    {
        cout << "在SQL Server中根据ID得到Department表一条记录" << endl;
    }
};
//AccessDepartment类,用于访问Access的Department
class AccessDepartment:public IDepartment
{
public:
    void Insert()
    {
        cout << "在Access中给Department表增加一条记录" << endl;
    }
    void GetUser()
    {
        cout << "在Access中根据ID得到Department表一条记录" << endl;
    }
};
//IFactory接口,定义一个创建访问Department表对象的抽象的工厂接口
class IFactory
{
public:
     virtual IUser *CreateUser()=0;
     virtual IDepartment *CreateDepartment()=0;
};
//SqlServerFactory类,实现IFactory接口,实例化SqlserverUser和SqlserverDepartment
class SqlServerFactory:public IFactory
{
public:
    IUser *CreateUser()
    {
        return new SqlserverUser();
    }
    IDepartment *CreateDepartment()
    {
        return new SqlserverDepartment();
    }
};
//AccessFactory类,实现IFactory接口,实现AccessUser和AccessDepartment
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 AccessFactory();
    IUser *iu=factory->CreateUser();
    iu->Insert();
    iu->GetUser();
    IDepartment *id=factory->CreateDepartment();
    id->Insert();
    id->GetUser();
    return 0;
}

  抽象工厂模式好处是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置;同时,它让具体的创建实例过程与客户端分离,客户端通过他们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

原文地址:https://www.cnblogs.com/awy-blog/p/3818613.html