[C++]抽象工厂模式

2023-10-27

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

C++代码如下:

// 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

// 参考大话设计模式 - 抽象工厂模式

// 各种工厂模式的区别:
// 简单工厂模式 :由客户端通知,工厂创建具体产品的对象
// 工厂模式     :由客户端选择创建具体产品的对象
// 抽象工厂模式 :客户端不需要关心不同工厂的具体实现,只需要调用工厂提供的接口即可。

#include <iostream>

#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif

using namespace std;

// 具体的用户信息类
class User {
public:
	string getname() {
		return name_;
	}
	void setname(string name) {
		name_ = name;
	}

	int getid() {
		return id_;
	}

	void setid(int id) {
		id_ = id;
	}

private:
	string name_ = "";
	int id_ = 0;
};

// 操作用户信息的抽象类,作为接口
class IOperateUserDB {
public:
	virtual void insert(User* user) = 0;
	virtual User* select(int id) = 0;
};

// 操作用户信息的具体实现类
class SqlOperateUserDB :public IOperateUserDB {
public:
	void insert(User* user) {
		cout << "sql insert user " << user->getname() << endl;
	}

	User* select(int id) {
		cout << "sql select id " << id << "from user table" << endl;
		return nullptr;
	}
};

// 操作用户信息的具体实现类
class AccessOperateUserDB :public IOperateUserDB {
public:
	void insert(User* user) {
		cout << "access insert user " << user->getname() << endl;
	}

	User* select(int id) {
		cout << "access select id " << id << "from user table" << endl;
		return nullptr;
	}
};

// 具体的部门信息类
class Department {
public:
	void setid(int id) {
		id_ = id;
	}
	int getid() {
		return id_;
	}
private:
	int id_ = 0;
};

// 操作部门信息的抽象类,作为接口
class IOperatePartDB {
public:
	virtual void insert(Department* department) = 0;
	virtual Department* select(int id) = 0;
};

// 操作部门信息的具体实现类
class SqlOperatePartDB :public IOperatePartDB {
public:
	void insert(Department* department) {
		cout << "sql insert department " << department->getid() << endl;
	}

	Department* select(int id) {
		cout << "sql select id " << id << "from department table" << endl;
		return nullptr;
	}
};

// 操作部门信息的具体实现类
class AccessOperatePartDB :public IOperatePartDB {
public:
	void insert(Department* department) {
		cout << "access insert department " << department->getid() << endl;
	}

	Department* select(int id) {
		cout << "access select id " << id << "from department table" << endl;
		return nullptr;
	}
};

/*
// 工厂抽象接口
class IFactory {
public:
	virtual IOperateUserDB* CreateUser() {
		return nullptr;
	}
	virtual IOperatePartDB* CreateDepartment() {
		return nullptr;
	}
};

// 具体的工厂实现类,实现了创建操作用户/部门对象的方法
class SqlServerFactory : public IFactory{
public:
	IOperateUserDB* CreateUser() {
		return new SqlOperateUserDB();
	}
	IOperatePartDB* CreateDepartment() {
		return new SqlOperatePartDB();
	}
};

// 具体的工厂实现类,实现了创建操作用户/部门对象的方法
class AccessFactory : public IFactory {
public:
	IOperateUserDB* CreateUser() {
		return new AccessOperateUserDB();
	}
	IOperatePartDB* CreateDepartment() {
		return new AccessOperatePartDB();
	}
};
*/

// 根据配置创建不同的操作用户/部门的对象
class ControlDatabase {
public:
	IOperateUserDB* CreateUser() {
		IOperateUserDB* opera_user = nullptr;
		switch (dbtype_) {
			case 1:
				opera_user = new SqlOperateUserDB();
				break;
			case 2:
				opera_user = new AccessOperateUserDB();
				break;
			default:
				break;
		}
		return opera_user;
	}

	IOperatePartDB* CreateDepartmentr() {
		IOperatePartDB* idepartment = nullptr;
		switch (dbtype_) {
		case 1:
			idepartment = new SqlOperatePartDB();
			break;
		case 2:
			idepartment = new AccessOperatePartDB();
			break;
		default:
			break;
		}
		return idepartment;
	}

	void setDbtype(int id) {
		dbtype_ = id;
	}
private:
	int dbtype_ = 2; // 1 sql 2 access
};

int main()
{
	/*
	IFactory* ifactory = new SqlServerFactory();
	//IFactory* ifactory = new AccessFactory();

	User* user = new User();
	user->setName("David");
	user->setId(27);
	Department* department = new Department();
	department->setId(297);

	IUser* usercurrent = ifactory->CreateUser();
	usercurrent->insert(user);
	usercurrent->select(27);
	IDepartment* departmentcurrent = ifactory->CreateDepartment();
	departmentcurrent->insert(department);
	departmentcurrent->select(297);
	*/

	ControlDatabase* dbbase = new ControlDatabase();
	dbbase->setDbtype(2);

	User* user = new User();
	user->setname("David");
	user->setid(27);
	Department* department = new Department();
	department->setid(297);

	// 用户和部门,不需要关心具体的数据库操作类的实现,只需要调用接口即可
	IOperateUserDB* usercurrent = dbbase->CreateUser();
	IOperatePartDB* departmentcurrent = dbbase->CreateDepartmentr();
	usercurrent->insert(user);
	usercurrent->select(27);
	departmentcurrent->insert(department);
	departmentcurrent->select(297);

	SAFE_DELETE(usercurrent);
	SAFE_DELETE(departmentcurrent);

	SAFE_DELETE(department);
	SAFE_DELETE(user);

	SAFE_DELETE(dbbase);

	return 0;
}

github源码路径:https://github.com/dangwei-90/Design-Mode

持续更新中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[C++]抽象工厂模式 的相关文章

随机推荐

  • 第46讲 Android Camera2 API AWB自动白平衡

    本讲是Android Camera专题系列的第46讲 我们介绍Android Camera2 API专题的AWB自动白平衡 包括如下内容 为什么要做白平衡 什么是自动白平衡 Android Camera颜色处理流程 AWB模式 AWB Lo
  • Java运算符优先级顺序

    Java运算符优先级顺序 图集说明 1 算数运算符 补充两个 单目运算符 正号 10 10 单目运算符 负号 n 10 n 10 1 除法规则 若两个操作数都是整型 结果也是整型 除数不能为0 若两个操作数有一个是浮点型 结果是浮点型 Sy
  • python爬虫十三:详细了解scrapy

    1 Scrapy log信息的认知 2019 01 19 09 50 48 scrapy utils log INFO Scrapy 1 5 1 started bot tencent 2019 01 19 09 50 48 scrapy
  • Matlab安装 MinGW-w64 编译器的方法

    最近用Matlab实现机器学习算法 学习到支持向量机时 提示需要运行lib svm包需要安装 MinGW w64 C 编译器 在这里把步骤列一下 1 下载MinGW w64 C 编译器 点击下载 安装时注意选择32位还是64位的 1 安装时
  • Windows混音器API使用

    1 首先用mixerGetNumDevs 函数获取系统中的混音器设备的数量 一般 机器上都至少有一个混音器设备 声卡 如果机器上没有连接其它的音频设备 那么也就只有声卡这一个混音器设备 我的机器上接有一个名为USB EMP Audio De
  • go-redis 框架基本使用

    文章目录 redis使用场景 下载框架和连接redis 1 安装go redis 2 连接redis 字符串操作 有序集合操作 流水线 事务 1 普通事务 2 Watch redis使用场景 缓存系统 减轻主数据库 MySQL 的压力 计数
  • 自适应控制设计(二)

    自适应控制设计 二 自适应控制基本思想 一文主要介绍了自适应控制设计的基本思路 但是针对控制率的设计没有具体说明 这里针对反馈控制率的设计步骤进行具体介绍 控制器设计基本思想 对于任何一个动态系统 我们都可以根据Lyapunov稳定性设计其
  • C++MFC编程之按钮控件Button、Radio Button和Check Box

    钮控件包括命令按钮 Button 单选按钮 Radio Button 和复选框 Check Box 等 命令按钮就是我们前面多次提到的狭义的按钮控件 用来响应用户的鼠标单击操作 进行相应的处理 它可以显示文本也可以嵌入位图 单选按钮使用时
  • 解决el-select下拉框多选在赋完值之后,不能对tag和已选中的值取消掉

    这种是原先的写法
  • 如何在Linux环境创建GRE Tunnel

    Question I want to connect to remote networks by using a GRE tunnel How can I create a GRE tunnel between two end points
  • ini配置文件读写操作入门

    ini配置文件读写操作入门 ini文件 Initialization file 这种类型的文件中通常存放的是一个程序的初始化信息 ini文件由若干个节 Section 组成 每个Section由若干键 Key 组成 每个Key可以赋相应的值
  • 大点云的可以用opencv和pcl结合粗配准

    比如 可以把点云转换为 tif 通过一部分截取8位图像 进行sift 将得到的内点序号序列 转换为三维坐标序列 然后将三维坐标转换为点云sift cloud1和sift cloud2 这时候 由于是一一对应的 即在pcl中 query in
  • 目标跟踪综述 (持续更新)

    这几天对目标跟踪挺感兴趣的 但是在CSDN和知乎上面找的相关介绍资料都看的一知半解 所以自己找了一篇 2022 04 26 发表的综述文章作下笔记学习下 目录 一 基于相关滤波的目标跟踪算法 1 相关滤波视频目标跟踪算法的框架 2 相关滤波
  • c#特性(Attribute)与反射(Reflection)学习

    概念 特性 Attribute 用于在运行时传递程序中各种元素 比如类 方法 结构 枚举 组件等 的行为信息的声明性标签 放置在他所修饰的元素前面用 包裹 用于添加元数据 如编译器指令和注释 描述 方法 类等其他信息 可以使用预定义的特性或
  • 通过SpringBoot生成微信小程序二维码,跳转指定页面

    以下通过两种方法实现生成微信小程序二维码保存 通过华为存储obs服务 通过 IO流 字符流的使用 读取字符流 字符流写入 微信小程序获取二维码参数 onLoad function options console log options 方式
  • qt 如何在另一个线程更新控件状态

    在 Qt 中 如果要在另一个线程中更新控件的状态 有以下几种方法可以考虑 使用信号和槽 在另一个线程中发射信号 连接到控件的槽函数 在槽函数中更新控件的状态 使用事件队列 在另一个线程中调用 QCoreApplication postEve
  • 手机投屏不是全屏怎么办_手机投屏到竖放的电视

    手机投屏到竖放的电视 今天有网友给我发了手机投屏电视 但是手机横屏之后 电视机还是竖屏 其实这个很正常 因为当手机与电视机处于镜像投屏模式的时候 因为显示比例的关系 电视机是不会满屏的 只能以竖屏模式在中间显示一部分画面 就像上面的图一样
  • Maven Install 报错:To see the full stack trace of the errors, re-run Maven with the -e switch

    博主 在eclipse打包项目 将war包部署到 linux 上 install 时的报错 蓝色标志 出现这个error信息 说明仓库里有些对应的jar包没下载完全 试过非常多办法就是不行 最后 处理方法是去到本地仓库里 把对应的jar包先
  • 【干货】日志管理与分析(一)——日志收集及来源

    对广大IT工作者 尤其是运维和安全人员来说 日志 是一个再熟悉不过的名词 日志从哪来 机房中的各种软件 系统 防火墙 和硬件 交换机 路由器等 都在不断地生成日志 IT安全业界的无数实践告诉我们 健全的日志记录和分析系统 是系统正常运营 优
  • [C++]抽象工厂模式

    抽象工厂模式 Abstract Factory Pattern 是围绕一个超级工厂创建其他工厂 该超级工厂又称为其他工厂的工厂 这种类型的设计模式属于创建型模式 它提供了一种创建对象的最佳方式 在抽象工厂模式中 接口是负责创建一个相关对象的