• 第十五章-抽象工厂模式


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

    图片

    IFactory是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。而ConcreteFactory1和ConcreteFactory2就是具体的工厂了。
    通常是在运行时刻在创建一个ConcreteFactory类的实例,这个具体的工厂再创建具有特定实现的产品对象,也就是说,为创建不同的产品对象,客户端应使用不同的具体工厂。

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    class User {};
    class Department {};
    
    class IUser
    {
    public:
    	virtual void Insert(User* user) = 0;
    	virtual User* GetUser(int id) = 0;
    };
    
    class SqlserverUser :public IUser
    {
    public:
    	void Insert(User* user)
    	{
    		cout << "在SQL Server中给User表增加一条记录" << endl;
    	}
    
    	User* GetUser(int id)
    	{
    		cout << "在SQL Server中根据ID得到User表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class AccessUser :public IUser
    {
    public:
    	void Insert(User* user)
    	{
    		cout << "在Access中给User表增加一条记录" << endl;
    	}
    
    	User* GetUser(int id)
    	{
    		cout << "在Access中根据ID得到User表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class IDepartment
    {
    public:
    	virtual void Insert(Department* department) = 0;
    	virtual Department* GetDeparment(int id) = 0;
    };
    
    class SqlserverDepartment :public IDepartment
    {
    public:
    	void Insert(Department* department)
    	{
    		cout << "在SQL Server中给Department表增加一条记录" << endl;
    	}
    
    	Department* GetDeparment(int id)
    	{
    		cout << "在SQL Server中根据ID得到Department表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class AccessDepartment :public IDepartment
    {
    public:
    	void Insert(Department* department)
    	{
    		cout << "在Access中给Department表增加一条记录" << endl;
    	}
    
    	Department* GetDeparment(int id)
    	{
    		cout << "在Access中根据ID得到Department表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class IFactory
    {
    public:
    	virtual IUser* CreateUser() = 0;
    
    	virtual IDepartment* CreateDepartment() = 0;
    };
    
    class SqlServerFactory :public IFactory
    {
    public:
    	IUser* CreateUser()
    	{
    		return new SqlserverUser();
    	}
    
    	IDepartment* CreateDepartment()
    	{
    		return new SqlserverDepartment();
    	}
    };
    
    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 SqlServerFactory();
    
    	IUser* iu = factory->CreateUser();
    
    	iu->Insert(user);
    	iu->GetUser(1);
    
    	IDepartment* id = factory->CreateDepartment();
    	id->Insert(dept);
    	id->GetDeparment(1);
    
    
    
    	system("pause");
    	return 0;
    }
    
    
    
    • 优点:一是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。再一点是它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
    • 缺点: 当需要增加需求是,比如添加一个Oracle数据库是,需要进行大批量的改动。

    用简单工厂来改进抽象工厂

    图片

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    class User {};
    class Department {};
    
    class IUser
    {
    public:
    	virtual void Insert(User* user) = 0;
    	virtual User* GetUser(int id) = 0;
    };
    
    class SqlserverUser :public IUser
    {
    public:
    	void Insert(User* user)
    	{
    		cout << "在SQL Server中给User表增加一条记录" << endl;
    	}
    
    	User* GetUser(int id)
    	{
    		cout << "在SQL Server中根据ID得到User表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class AccessUser :public IUser
    {
    public:
    	void Insert(User* user)
    	{
    		cout << "在Access中给User表增加一条记录" << endl;
    	}
    
    	User* GetUser(int id)
    	{
    		cout << "在Access中根据ID得到User表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class IDepartment
    {
    public:
    	virtual void Insert(Department* department) = 0;
    	virtual Department* GetDeparment(int id) = 0;
    };
    
    class SqlserverDepartment :public IDepartment
    {
    public:
    	void Insert(Department* department)
    	{
    		cout << "在SQL Server中给Department表增加一条记录" << endl;
    	}
    
    	Department* GetDeparment(int id)
    	{
    		cout << "在SQL Server中根据ID得到Department表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class AccessDepartment :public IDepartment
    {
    public:
    	void Insert(Department* department)
    	{
    		cout << "在Access中给Department表增加一条记录" << endl;
    	}
    
    	Department* GetDeparment(int id)
    	{
    		cout << "在Access中根据ID得到Department表一条记录" << endl;
    		return nullptr;
    	}
    };
    
    class DataAccess
    {
    private:
    	static const string db;
    public:
    	static IUser* CreateUser()
    	{
    		IUser* result = nullptr;
    		if (db == "Sqlserver")
    		{
    			result = new SqlserverUser();
    		}
    		else if (db == "Access")
    		{
    			result = new AccessUser();
    		}
    
    		return result;
    	}
    
    	static IDepartment* CreateDepartment()
    	{
    		IDepartment* result = nullptr;
    		if (db == "Sqlserver")
    		{
    			result = new SqlserverDepartment();
    		}
    		else if (db == "Access")
    		{
    			result = new AccessDepartment();
    		}
    
    		return result;
    	}
    
    };
    const string DataAccess::db = "Sqlserver";
    
    
    int main()
    {
    	User* user = new User();
    	Department* dept = new Department();
    
    	IUser* iu = DataAccess::CreateUser();
    
    	iu->Insert(user);
    	iu->GetUser(1);
    
    	IDepartment* id = DataAccess::CreateDepartment();
    	id->Insert(dept);
    	id->GetDeparment(1);
    
    
    	system("pause");
    	return 0;
    }
    
    

    用反射+抽象工厂
    .......................

  • 相关阅读:
    并行数据的并行转串行
    色彩空间转换仿真与模型搭建
    布隆过滤器介绍和在java中应用举例
    java9初探
    个人博客开通啦!
    MyBatis多租户隔离插件开发
    手动解析Excel获取文件元数据
    解决Shiro+SpringBoot自定义Filter不生效问题
    基于Redis的分布式锁实现
    解决tomcat同时部署两个SpringBoot应用提示InstanceAlreadyExistsException
  • 原文地址:https://www.cnblogs.com/wfcg165/p/12023030.html
Copyright © 2020-2023  润新知