抽象工厂模式与单件模式C++混合实现

在这里插入图片描述

抽象工厂

当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

单件模式

Singleton就是确保一个类只有唯一的一个实例。Singleton主要用于对象的创建,这意味着,如果某个类采用了Singleton模式,则在这个类被创建后,它将有且仅有一个实例可供访问。很多时候我们都会需要Singleton模式,最常见的比如我们希望整个应用程序中只有一个连接数据库的Connection实例;又比如要求一个应用程序中只存在某个用户数据结构的唯一实例。我们都可以通过应用Singleton模式达到目的。
具体请看:
http://www.omegaxyz.com/2019/03/19/design-pattern-singleton/

实例

该公司数据库拥有三张表,分别是用户表、部门表和项目表。每张表的操作都支持查询和添加功能。数据库支持MySQL和SQL Server两种。结合抽象工厂模式和单件模式给出该系统的模拟代码。

在抽象工厂模式中,一个应用里一般每个产品只需要一个具体工厂的实例,因此,工厂通常最好用单件模式实现。实验要求结合抽象工厂模式和单件模式,模拟公司数据库创建过程。

UML

在这里插入图片描述

C++代码

#include<iostream>
using namespace std;
 
 
class User{
    int id;
};
 
class Department{
    int id;
};
 
class Project{
    int id;
};
 
 
 
 
class IUser{
public:
    virtual void Insert(User* user) = 0;
    virtual User* GetUser(int id) = 0;
};
 
class IDepartment{
public:
    virtual void Insert(Department* department) = 0;
    virtual Department* GetDepartment(int id) = 0;
};
 
class IProject{
public:
    virtual void Insert(Project* project) = 0;
    virtual Project* GetProject(int id) = 0;
};
 
class IFactory{
public:
    virtual ~IFactory(){cout<<"抽象工厂实例删除!"<<endl;}
    virtual IUser* CreateUser()=0;
    virtual IDepartment* CreateDepartment()=0;
    virtual IProject* CreateProject()=0;    
};
 
class SqlserverUser: public IUser{
public:
    void Insert(User* user){
        cout<<"增加一个用户"<<endl;
    }
    User* GetUser(int id){
        cout<<"得到一个用户"<<endl;
        return NULL;
    }
};
 
class SqlserverDepartment: public IDepartment{
public:
    void Insert(Department* department){
        cout<<"增加一个部门"<<endl;
    }
    Department* GetDepartment(int id){
        cout<<"得到一个部门"<<endl;
        return NULL;
    }
};
 
class SqlserverProject: public IProject{
public:
    void Insert(Project* project){
        cout<<"增加一个项目"<<endl;
    }
    Project* GetProject(int id){
        cout<<"得到一个项目"<<endl;
        return NULL;
    }
};
 
class MysqlUser: public IUser{
public:
    void Insert(User* user){
        cout<<"增加一个用户"<<endl;
    }
    User* GetUser(int id){
        cout<<"得到一个用户"<<endl;
        return NULL;
    }
};
 
class MysqlDepartment: public IDepartment{
public:
    void Insert(Department* department){
        cout<<"增加一个部门"<<endl;
    }
    Department* GetDepartment(int id){
        cout<<"得到一个部门"<<endl;
        return NULL;
    }
};
 
class MysqlProject: public IProject{
public:
    void Insert(Project* project){
        cout<<"增加一个项目"<<endl;
    }
    Project* GetProject(int id){
        cout<<"得到一个项目"<<endl;
        return NULL;
    }
};
 
 
class SqlserverFactory: public IFactory{
public:
    ~SqlserverFactory(){cout<<"SQL Server抽象工厂实例删除!"<<endl;}
    IUser* CreateUser(){
        return new SqlserverUser();
    }
    IDepartment* CreateDepartment(){
        return new SqlserverDepartment();
    }
    IProject* CreateProject(){
        return new SqlserverProject();
    }
    static IFactory *GetInstance(){
        if (factory == NULL ){
                return new SqlserverFactory();
                cout<<"抽象工厂实例生成!"<<endl;
        
        }else cout<<"Error, 抽象工厂实例已有!"<<endl;
        return factory;
    }
private:
    
    SqlserverFactory(){}
    static SqlserverFactory* factory;
};
SqlserverFactory* SqlserverFactory::factory = NULL;
 
 
 
class MysqlFactory: public IFactory{
public:
    ~MysqlFactory(){cout<<"SQL Server抽象工厂实例删除!"<<endl;}
    IUser* CreateUser(){
        return new MysqlUser();
    }
    IDepartment* CreateDepartment(){
        return new MysqlDepartment();
    }
    IProject* CreateProject(){
        return new MysqlProject();
    }
    static IFactory *GetInstance(){
        if (factory == NULL ){
            cout<<"抽象工厂实例生成!"<<endl;
            factory =  new MysqlFactory();
                
        }else cout<<"Error, 抽象工厂实例已有!"<<endl;
        return factory;
    }
private:
    MysqlFactory(){}
    static MysqlFactory* factory;
};
MysqlFactory* MysqlFactory::factory = NULL;
 
int main(){
    User* user = new User();
    Department* dept = new Department();
    Project* pro = new Project();
 
 
    cout<<endl<<"MySQL"<<endl;
    IFactory *factory1 = MysqlFactory::GetInstance();
    IFactory *factory2 = MysqlFactory::GetInstance();
    //生成第二个失败
    IUser* iu = factory1->CreateUser();
    iu->Insert(user);
    iu->GetUser(1);
    
    IDepartment* idept = factory1->CreateDepartment();
    idept->Insert(dept);
    idept->GetDepartment(1);
 
    IProject* ipro = factory1->CreateProject();
    ipro->Insert(pro);
    ipro->GetProject(1);
 
    cout<<endl<<"SQL Server"<<endl;
    IFactory *factory12 = MysqlFactory::GetInstance();
    IFactory *factory22 = MysqlFactory::GetInstance();
    //生成第二个失败
    IUser* iu2 = factory12->CreateUser();
    iu->Insert(user);
    iu->GetUser(1);
    
    IDepartment* idept2 = factory12->CreateDepartment();
    idept->Insert(dept);
    idept->GetDepartment(1);
 
    IProject* ipro2 = factory12->CreateProject();
    ipro->Insert(pro);
    ipro->GetProject(1);
    return 0;
}

结果

在这里插入图片描述
注意第二行是再次生成一个MySQL的工厂,但是由于只能有一个,因此不能再次创建。

总结

注意使用单件模式写MySQL和SQL Server的具体工厂时,只能对自身单件,即生成一个MySQL工厂时,不能再次生成第二个MySQL工厂,但是可以生成SQL Server工厂。

当使用单件模式时,具体工厂的构造函数需要放在private中,这样客户端不能随意创建多个工厂。在public中需要增加getInstance函数用来判断是否生成了工厂,如果存在,则不能创建第二个,注意这是static类型。

具体工厂的指针需要在类外部全局部分进行初始化为NULL。

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2019 • OmegaXYZ-版权所有 转载请注明出处

发布了242 篇原创文章 · 获赞 500 · 访问量 125万+

猜你喜欢

转载自blog.csdn.net/xyisv/article/details/97107018