设计模式(C++实现)(十三)——抽象工厂模式

示例问题:

一个项目最初使用SQLServer数据库,后来根据项目情况要使用mysql数据库,此时需要更改所有和数据库有关的接口,工作量大,如果后期又要切换成PostgreSQL数据库,则所有和数据库有关的接口又要都改一遍。有没有方法能够在切换数据库的时候,不修改这么多接口?

分析:

可使用这个思路来解决:确定一个厂商的工厂,就可以确定所有物品都是来源于该厂商。比如要获取耐克的鞋、裤子、上衣、袜子等,则创建耐克这个厂商的工厂,然后从该工厂中取出来的鞋子,一定就是耐克的鞋子了。

解决方案:

AbstractFactory.h

该文件实现了用户数据基类(IUser)、部门数据基类(IDepartment)、工厂类基类(IFactory)。以及SQLServer用户数据类CSQLServerUser(继承IUser)、Mysql用户数据类CMysqlUser(继承IUser);SQLServer部门数据类CSQLServerDepartment(继承IDepartment)、Mysql部门数据类CMysqlDepartment(继承IDepartment);SQLServer工厂类CSQLServerFactory(继承IFactory)、Mysql工厂类CMysqlFactory(继承IFactory)。

调用工厂类CSQLServerFactory或者CMysqlFactory的CreateUser、CreateDepartment方法,则可创建针对不同数据库类型造作的对象。这样可以做到,当切换不同的数据库时,只需修改工厂类(继承IFactory的类)的创建即可。

#pragma once

#include <iostream>

//用户数据基类
class IUser
{
public:
	IUser()
	{

	}

	virtual ~IUser()
	{

	}

	virtual void InsertUser() = 0;
	virtual void GetUser() = 0;
};

//SQLServer用户数据类
class CSQLServerUser : public IUser
{
public:
	CSQLServerUser()
	{

	}

	virtual ~CSQLServerUser()
	{

	}

	void InsertUser()
	{
		std::cout << "SQLServer数据库插入用户数据" << std::endl;
	}

	void GetUser()
	{
		std::cout << "SQLServer数据库取出用户数据" << std::endl;
	}
};

//Mysql用户数据类
class CMysqlUser : public IUser
{
public:
	CMysqlUser()
	{

	}

	virtual ~CMysqlUser()
	{

	}

	void InsertUser()
	{
		std::cout << "Mysql数据库插入用户数据" << std::endl;
	}

	void GetUser()
	{
		std::cout << "Mysql数据库取出用户数据" << std::endl;
	}
};

//部分数据基类
class IDepartment
{
public:
	IDepartment()
	{

	}

	virtual ~IDepartment()
	{

	}

	virtual void InsertDepartment() = 0;
	virtual void GetDepartment() = 0;
};

//SQLServer部门数据类
class CSQLServerDepartment : public IDepartment
{
public:
	CSQLServerDepartment()
	{

	}

	virtual ~CSQLServerDepartment()
	{

	}

	void InsertDepartment()
	{
		std::cout << "SQLServer数据库插入部门数据" << std::endl;
	}

	void GetDepartment()
	{
		std::cout << "SQLServer数据库取出部门数据" << std::endl;
	}
};

//Mysql部门数据类
class CMysqlDepartment : public IDepartment
{
public:
	CMysqlDepartment()
	{

	}

	virtual ~CMysqlDepartment()
	{

	}

	void InsertDepartment()
	{
		std::cout << "Mysql数据库插入部门数据" << std::endl;
	}

	void GetDepartment()
	{
		std::cout << "Mysql数据库取出部门数据" << std::endl;
	}
};

//工厂基类
class IFactory
{
public:
	IFactory()
	: m_pUser(nullptr)
	, m_pDepartment(nullptr)
	{

	}

	virtual ~IFactory()
	{

	}

	virtual IUser* CreateUser() = 0;
	virtual IDepartment* CreateDepartment() = 0;
	void DelUser()
	{
		if (nullptr != m_pUser)
		{
			delete m_pUser;
			m_pUser = nullptr;
		}
	}
	void DelDepartment()
	{
		if (nullptr != m_pDepartment)
		{
			delete m_pDepartment;
			m_pDepartment = nullptr;
		}
	}

	IUser* m_pUser;
	IDepartment* m_pDepartment;
};

//SQLServer工厂类
class CSQLServerFactory : public IFactory
{
public:
	CSQLServerFactory()
	{

	}

	virtual ~CSQLServerFactory()
	{

	}

	IUser* CreateUser()
	{
		m_pUser = new(std::nothrow) CSQLServerUser();
		return m_pUser;
	}

	IDepartment* CreateDepartment()
	{
		m_pDepartment = new(std::nothrow) CSQLServerDepartment();
		return m_pDepartment;
	}
};

//Mysql工厂类
class CMysqlFactory : public IFactory
{
public:
	CMysqlFactory()
	{

	}

	virtual ~CMysqlFactory()
	{

	}

	IUser* CreateUser()
	{
		m_pUser = new(std::nothrow) CMysqlUser();
		return m_pUser;
	}

	IDepartment* CreateDepartment()
	{
		m_pDepartment = new(std::nothrow) CMysqlDepartment();
		return m_pDepartment;
	}
};

main.cpp

// main.cpp : Defines the entry point for the console application.
//

#include "AbstractFactory.h"


int main()
{
	CSQLServerFactory SQLServerFactory;//SQLServer数据库工厂
	IUser* pUserSQLServer = SQLServerFactory.CreateUser();//创建操作SQLServer数据库用户数据的对象指针
	IDepartment* pDepartmentSQLServer = SQLServerFactory.CreateDepartment();//创建操作SQLServer数据部门数据的对象指针
	pUserSQLServer->InsertUser();
	pUserSQLServer->GetUser();
	pDepartmentSQLServer->InsertDepartment();
	pDepartmentSQLServer->GetDepartment();
	SQLServerFactory.DelUser();
	SQLServerFactory.DelDepartment();

	CMysqlFactory MysqlFactory;//Mysql数据库工厂
	IUser* pUserMysql = MysqlFactory.CreateUser();//创建操作mysql数据库用户数据的对象指针
	IDepartment* pDepartmentMysql = MysqlFactory.CreateDepartment();//创建操作mysql数据部门数据的对象指针
	pUserMysql->InsertUser();
	pUserMysql->GetUser();
	pDepartmentMysql->InsertDepartment();
	pDepartmentMysql->GetDepartment();
	MysqlFactory.DelUser();
	MysqlFactory.DelDepartment();

	system("pause");
    return 0;
}

运行结果

抽象工厂模式解决的问题:

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

抽象工程模式的好处:

1. 易于切换产品系列。创建不同的工厂,即可切换所有产品;

2. 具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

 

返回目录:设计模式(C++实现)(总)

上一篇:设计模式(C++实现)(十二)——观察者模式

下一篇:设计模式(C++实现)(十四)——适配器模式

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值