抽象工厂模式(大话设计模式)C/C++版本

news2024/11/26 20:23:11

抽象工厂模式

在这里插入图片描述

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15927110.html

#include <iostream>
using namespace std;

// 抽象产品Department ,定义具体产品的公共接口
class Department
{
public:
    virtual ~Department() = default;
    virtual void Insert() = 0;
    virtual Department *GetDepartment() = 0;
};

// 创建具体产品类SqlserDepartment, 定义生产的具体产品;
class SqlserDepartment : public Department
{
public:
    void Insert() override
    {
        cout << "在SQL Server 中给 Department 表增加一条记录!" << endl;
    }
    Department *GetDepartment() override
    {
        cout << "在SQL Server 中根据ID 得到 Department 表一条记录!" << endl;
        return nullptr;
    }
};

// 创建具体产品类AccessDepartment, 定义生产的具体产品;
class AccessDepartment : public Department
{
public:
    void Insert() override
    {
        cout << "在 Access 中给 Department 表增加一条记录!" << endl;
    }
    Department *GetDepartment() override
    {
        cout << "在 Access 中根据ID 得到 Department 表一条记录!" << endl;
        return nullptr;
    }
};

// 抽象产品User ,定义具体产品的公共接口
class User
{
public:
    virtual ~User() = default;
    virtual void Insert() = 0;
    virtual User *GetUser() = 0;
};

// 创建具体产品类SqlserverUser, 定义生产的具体产品;
class SqlserverUser : public User
{
public:
    void Insert() override
    {
        cout << "在SQL Server 中给 User表增加一条记录!" << endl;
    }
    User *GetUser() override
    {
        cout << "在SQL Server 中根据ID 得到 User表一条记录!" << endl;
        return nullptr;
    }
};

// 创建具体产品类AccessUser, 定义生产的具体产品;
class AccessUser : public User
{
public:
    void Insert() override
    {
        cout << "在 Access 中给 User表增加一条记录!" << endl;
    }
    User *GetUser() override
    {
        cout << "在 Access 中根据ID 得到 User表一条记录!" << endl;
        return nullptr;
    }
};

// 抽象工厂,定义具体工厂的公共接口
class AbstractFactory
{
public:
    virtual ~AbstractFactory() = default;
    virtual User *CreateUser() = 0;
    virtual Department *CreateDepartment() = 0;
};

// 创建具体工厂SqlServerFactory,定义创建对应具体产品实例的方法;
class SqlServerFactory : public AbstractFactory
{
public:
    User *CreateUser() override
    {
        return new SqlserverUser(); // 该工厂 生产的产品
    }
    Department *CreateDepartment() override
    {
        return new SqlserDepartment;
    }
};

// 创建具体工厂AccessFactory,定义创建对应具体产品实例的方法;
class AccessFactory : public AbstractFactory
{
public:
    User *CreateUser() override
    {
        return new AccessUser(); // 该工厂 生产的产品
    }
    Department *CreateDepartment() override
    {
        return new AccessDepartment;
    }
};

int main()
{
    // AbstractFactory *factory = new SqlServerFactory;
    AbstractFactory *factory = new AccessFactory;

    // 调用的是 AccessFactory 工厂,准备生产  SqlserverUser 产品
    User *iu = factory->CreateUser();
    iu->Insert();
    iu->GetUser();

    // 调用的是 AccessFactory 工厂,准备生产  AccessDepartment 产品
    Department *id = factory->CreateDepartment();
    id->Insert();
    id->GetDepartment();

    delete factory;
    delete iu;
    delete id;
    factory = nullptr;
    id = nullptr;
    id = nullptr;
    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>

// 抽象产品Department
typedef struct Department
{
    void (*Insert)(void *);
    struct Department *(*GetDepartment)(void *);
} Department;

// 抽象产品User
typedef struct User
{
    void (*Insert)(void *);
    struct User *(*GetUser)(void *);
} User;

// 抽象工厂
typedef struct AbstractFactory
{
    User *(*CreateUser)(void);
    Department *(*CreateDepartment)(void);
} AbstractFactory;

// 具体产品SqlserDepartment
typedef struct SqlserDepartment
{
    Department base;
} SqlserDepartment;

void SqlserDepartment_Insert(void *dept)
{
    printf("在SQL Server 中给 Department 表增加一条记录!\n");
}

Department *SqlserDepartment_GetDepartment(void *dept)
{
    printf("在SQL Server 中根据ID 得到 Department 表一条记录!\n");
    return NULL;
}

// 具体产品AccessDepartment
typedef struct AccessDepartment
{
    Department base;
} AccessDepartment;

void AccessDepartment_Insert(void *dept)
{
    printf("在 Access 中给 Department 表增加一条记录!\n");
}

Department *AccessDepartment_GetDepartment(void *dept)
{
    printf("在 Access 中根据ID 得到 Department 表一条记录!\n");
    return NULL;
}

// 具体产品SqlserverUser
typedef struct SqlserverUser
{
    User base;
} SqlserverUser;

void SqlserverUser_Insert(void *user)
{
    printf("在SQL Server 中给 User表增加一条记录!\n");
}

User *SqlserverUser_GetUser(void *user)
{
    printf("在SQL Server 中根据ID 得到 User表一条记录!\n");
    return NULL;
}

// 具体产品AccessUser
typedef struct AccessUser
{
    User base;
} AccessUser;

void AccessUser_Insert(void *user)
{
    printf("在 Access 中给 User表增加一条记录!\n");
}

User *AccessUser_GetUser(void *user)
{
    printf("在 Access 中根据ID 得到 User表一条记录!\n");
    return NULL;
}

// 具体工厂SqlServerFactory
typedef struct SqlServerFactory
{
    AbstractFactory base;
} SqlServerFactory;

User *SqlServerFactory_CreateUser(void *unused)
{
    SqlserverUser *user = (SqlserverUser *)malloc(sizeof(SqlserverUser));
    user->base.Insert = SqlserverUser_Insert;
    user->base.GetUser = SqlserverUser_GetUser;
    return (User *)user;
}

Department *SqlServerFactory_CreateDepartment(void *unused)
{
    SqlserDepartment *dept = (SqlserDepartment *)malloc(sizeof(SqlserDepartment));
    dept->base.Insert = SqlserDepartment_Insert;
    dept->base.GetDepartment = SqlserDepartment_GetDepartment;
    return (Department *)dept;
}

// 具体工厂AccessFactory
typedef struct AccessFactory
{
    AbstractFactory base;
} AccessFactory;

User *AccessFactory_CreateUser()
{
    AccessUser *user = (AccessUser *)malloc(sizeof(AccessUser));
    user->base.Insert = AccessUser_Insert;
    user->base.GetUser = AccessUser_GetUser;
    return (User *)user;
}

Department *AccessFactory_CreateDepartment()
{
    AccessDepartment *dept = (AccessDepartment *)malloc(sizeof(AccessDepartment));
    dept->base.Insert = AccessDepartment_Insert;
    dept->base.GetDepartment = AccessDepartment_GetDepartment;
    return (Department *)dept;
}

int main()
{
    AbstractFactory *factory = (AbstractFactory *)malloc(sizeof(AccessFactory));
    ((AccessFactory *)factory)->base.CreateUser = AccessFactory_CreateUser;
    ((AccessFactory *)factory)->base.CreateDepartment = AccessFactory_CreateDepartment;

    User *iu = factory->CreateUser();
    iu->Insert(iu);
    iu->GetUser(iu);

    Department *id = factory->CreateDepartment();
    id->Insert(id);
    id->GetDepartment(id);

    free(factory);
    free(iu);
    free(id);

    return 0;
}

总结

在工厂方法模式的基础上,在对应的工厂类中新增了相关产品的创建函数。(其实并不是很方便!!)

扩展:
简单工厂模式似乎更简便点,但是switch部分实在是破坏了开闭原则,可以使用“反射”(即动态识别类型)

C++可以使用静态函数指针数组来实现
参考:https://blog.csdn.net/klarclm/article/details/7352101

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1825977.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

next.js v14 升级全步骤|迁移 pages Router 到 App Router

【概括】本文升级整体按照官网文档指引进行&#xff0c;在迁移 pages Router 前先看了官网的实操视频。 【注意】文章内对 .babel.ts、next.config.js 进行了多次更改&#xff0c;最终配置可见 报错3: Server Error ReferenceError: React is not defined 一、升级 Next.js 版…

Boom 3D软件下载及安装教程

简介&#xff1a; Boom 3D是适用于Mac和Windows系统的专业音效增强软件&#xff0c;旨在通过播放器&#xff0c;媒体或流媒体服务等介质&#xff0c;在不同类型的耳机上以3D环绕效果播放媒体内容。您无需使用昂贵的耳机或其他附加环绕音效增强器即可感受3D环绕音乐。 安 装 包…

性能测试包括哪些方面?

性能测试、通过自动化测试工具模拟多种正常&#xff0c;峰值&#xff0c;以及异常的负载情况下对系统各项性能指标进行的测试。 负载测试、压力测试、容量测试都属于性能测试。 性能测试指标是衡量系统性能的评价标准 主要关注一些响应时间、并发用户/并发、点击率、吞吐量、…

助力知识博主,实现在家搞副业的FlowUs新策略

助力知识博主&#xff0c;实现在家副业的FlowUs新策略 我们设定了一个雄心勃勃的目标&#xff1a;帮助100位知识博主在FlowUs上实现副业成功。这个目标不仅得到了团队成员的广泛支持&#xff0c;甚至有人认为它过于保守&#xff0c;因为FlowUs的多功能性使其成为自媒体博主收入…

工资信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;基础数据管理&#xff0c;公告管理&#xff0c;津贴管理&#xff0c;管理员管理&#xff0c;绩效管理 用户账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;津…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(五)质量设计方法与工具

第五节 质量设计方法与工具 1 任 务 分 解 法 1.1 概念 任务分解法&#xff0c;又称工作分解结构 (Work Breakdown Structure, 简 称 WBS) 。WBS 指以可交付成果为 导向&#xff0c;对项目团队为实现项目目标并完成规定的可交付成果而执行的工作所进行的层次分解。W…

057、PyCharm 运行代码报错:Error Please select a valid Python interpreter

当我们在PyCharm运行代码时&#xff0c;提示如下图错误&#xff1a; 那么问题通常是由于PyCharm未正确配置Python解释器引起的。 我们只需按以下步骤重新配置Python解释器即可&#xff1a; 打开PyCharm设置&#xff1a; 在菜单栏中的点击 “File” -> “Settings”&#xf…

【Spine学习09】之导入皮肤两种方式[skin]

第一种&#xff1a;明确项目中某个角色是有两套皮肤的情况下 直接导入两套皮肤 1、添加SKIN皮肤指令 2、在ps中-文件-脚本-浏览【打开选中jsx脚本】 3、打开Spine 点击左上角&#xff0c;选择导入数据 就可以看到该角色的两套皮肤啦&#xff01; 第二种&#xff1a;刚开始角…

Android开发更改JDK版本

今天在跑GitHub上面一个Android项目时&#xff0c;在Android编译时出现如下错误&#xff1a; Unsupported Java. Your build is currently configured to use Java 17.0.2 and Gradle 7.0.2.错误原因&#xff1a; JDK和Gradle版本对应出错。 本地的JDK为1.8正好可以更改为本…

商品搬家到抖店

使用的工具为 张飞搬家&#xff0c;登录上去 张飞搬家 1 复制商品的网址 商品链接复制过去后&#xff0c;点击下面的开始批量复制 2 检查修改商品信息 价格啊、图片啊、各种商品属性啊&#xff0c;检查下&#xff0c;不合适的修改和补充 3 开始搬家 4 查看商品 打开抖店后…

配置完eslint没有用?

当你使用 npx eslint --init 生成配置文件后 你也配置好了.prettierrc 当你在代码写一点小问题的时候 发现eslint没有进行检查 原因是你生成的 .eslintrc.js中没有加上这个配置 extends: [.....plugin:prettier/recommended],加上以后重启vscode你会发现

用AI造谣每天收入1万元,最后只拘留5日?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 当时我就震惊了!800多个MCN的自媒体账号每天收入1万元&#xff0c;最后拘留5日?难怪群里这么多人在晒收益截图&#xff0c;原来都是这样来的。 央视刚刚曝光一家MCN机构用AI造谣的事件&#xff0c;该公司用AI一天…

Servlet接口实现

项目搭建 pom文件引入依赖与打包配置。 <dependencies><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId>…

Linux笔记--vi编辑器

vi编辑器 基本操作 对于vi编辑器有这几种模式 移动 当编辑一个过大的文件时通过方向键移动光标过慢所以可以使用快捷键进行移动 编辑 dw指令只能在单词第一个字母处使用 D指令删除的是当前行 查找替换 pattern指代想要搜索的内容

HAL库开发--STM32的HAL环境搭建

知不足而奋进 望远山而前行 目录 文章目录 前言 下载 安装 解压 安装 添加开发包 修改仓库路径 下载软件开发包&#xff08;慢&#xff0c;不推荐&#xff09; 解压已有软件开发包&#xff08;快&#xff0c;推荐&#xff09; 总结 前言 在嵌入式系统开发中&#x…

系统架构师考点--计算机硬件

大家好。今天我总结一下计算机硬件的一些考点。 一、中央处理单元&#xff08;CPU&#xff09; 我们知道&#xff0c;计算机的基本硬件系统由运算器、控制器、存储器、输入设备和输出设备5大部件组成。其中运算器、控制器等部件被集成在一起统称为中央处理单元(Central Proce…

微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门

Elasticsearch ES简介 分布式全文搜索引擎 我们天天在用ES 搜索的时候 要与多个信息进行匹配查找 然后返回给用户 首先 ES会将数据库中的信息 先进行一个拆分 这个叫做分词 是按照词语关键词拆的 然后就能进行搜索的时候匹配对应的id 每一个关键字对应若干id 每一个…

2024年实体门店和企业怎么做短视频矩阵?一文带你了解清楚

不知道大家有没有刷到过这个直播间&#xff0c;潮汕一位做牛丸的大哥&#xff0c;看起来直播间内容平平无奇&#xff0c;也就几十个人的直播间观看&#xff0c;但是他通过短视频矩阵的方式卖了150万单牛丸你敢信&#xff1f; 那你猜猜他通过短视频矩阵发了多少条视频&#xff…

LaTeX 学习 第1节 数学模型概说

----用教授的方式学习 https://download.csdn.net/download/weixin_38135241/89416392 LaTex 安装包 LaTeX 有多种工作模式&#xff1a;输入一行文字时我们在水平模式&#xff0c;在水平模式上&#xff0c;文字、符号等各种排版元素&#xff0c;也就是各种盒子&#xff0c;都…

JavaScript常见面试题(一)

文章目录 1. JavaScript有哪些数据类型&#xff0c;它们的区别&#xff1f;2.数据类型检测的方式有哪些3. 判断数组的方式有哪些4.null和undefined区别5.typeof null 的结果是什么&#xff0c;为什么&#xff1f;6.intanceof 操作符的实现原理及实现7.为什么0.10.2 ! 0.3&…