C语言 | 简单工厂方法模式实现例子

点击蓝字

c84429785780eedb9a38a575e8e82e26.png

关注我们

1、简介

简单工厂方法定义一个用于创建对象的类,该类接受一个参数,通过参数决定创建不同的对象。

GOF并没有把简单工厂方法定义为23种设计模式之一,可以认为简单工厂方法是工厂方法的简化形式。

为了体现简单工厂方法和工厂方法的区别和联系,此处把简单工厂方法先单独讲一下。

2、模拟场景

假设你要生产电脑,电脑由硬盘、内存条、CPU、主板的部件组成。你为了保证供应链可靠,每种部件都选择了至少两家供应商。比如:

硬盘供应商 seagate、Toshiba

内存条供应商 SAMSUNG、Crucial

CPU供应商 intel、AMD

主板供应商 intel、AMD

此处列出多个部件是为了后面讲解工厂方法、抽象工厂方法时使用同一个模拟场景。本章讲简单工厂方法暂时不需要涉及这么多部件,所以仅以硬盘这一个部件为例进行讲解。

3、实现的思路

硬盘就是要创建的对象(即:产品)。为了让不同供应商提供的硬盘可以通用,要定义一个硬盘产品类,并让不同供应商的硬盘都继承硬盘产品类的接口。

还需要定义一个创建硬盘对象的类(即:工厂)。工厂类根据参数决定创建哪家供应商的硬盘对象。

4、实现硬盘对象创建

参与者:

(1)Product: HardDisk 定义硬盘对象的接口

(2)Concrete Product: SeagateHardDisk, ToshibaHardDisk 实现不同供应商的硬盘

(3)SimpleFactory: HardDiskFactory 根据参数,创建不同供应商的硬盘对象

UML:

01f2c245e2781687eefb696abe1ec34b.png

HardDisk代码示例:

hard_disk.h:

#ifndef HARD_DISK_H
#define HARD_DISK_Hstruct HardDisk {void (*Operation)(struct HardDisk *this);
};#endif

SeagateHardDisk代码示例:

seagate_hard_disk.h:

#ifndef SEAGATE_HARD_DISK_H
#define SEAGATE_HARD_DISK_H#include "hard_disk.h"struct SeagateHardDisk {struct HardDisk hardDisk;
};// 构造函数
void SeagateHardDisk(struct SeagateHardDisk *this);// 析构函数
void _SeagateHardDisk(struct SeagateHardDisk *this);#endif

seagate_hard_disk.c:

#include "seagate_hard_disk.h"
#include "stdio.h"void SeagateOperation(struct SeagateHardDisk *this)
{printf("这是 Seagate 硬盘\n");
}void SeagateHardDisk(struct SeagateHardDisk *this)
{this->hardDisk.Operation = (void(*)(struct HardDisk *))SeagateOperation;
}void _SeagateHardDisk(struct SeagateHardDisk *this)
{this->hardDisk.Operation = NULL;
}

ToshibaHardDisk代码示例:

toshiba_hard_disk.h:

#ifndef TOSHIBA_HARD_DISK_H
#define TOSHIBA_HARD_DISK_H#include "hard_disk.h"struct ToshibaHardDisk {struct HardDisk hardDisk;
};// 构造函数
void ToshibaHardDisk(struct ToshibaHardDisk *this);// 析构函数
void _ToshibaHardDisk(struct ToshibaHardDisk *this);#endif

toshiba_hard_disk.c:

#include "toshiba_hard_disk.h"
#include "stdio.h"void ToshibaOperation(struct ToshibaHardDisk *this)
{printf("这是 Toshiba 硬盘\n");
}void ToshibaHardDisk(struct ToshibaHardDisk *this)
{this->hardDisk.Operation = (void(*)(struct HardDisk *))ToshibaOperation;
}void _ToshibaHardDisk(struct ToshibaHardDisk *this)
{this->hardDisk.Operation = NULL;
}

HardDiskFactory代码示例:

hard_disk_factory.h:

#ifndef HARD_DISK_FACTORY_H
#define HARD_DISK_FACTORY_H#include "hard_disk.h"enum HARD_DISK_SUPPLIER_E {HARD_DISK_SUPPLIER_SEAGATE,HARD_DISK_SUPPLIER_TOSHIBA
};struct HardDiskFactory {struct HardDisk* (*Create)(struct HardDiskFactory *this, enum HARD_DISK_SUPPLIER_E supplier);void (*Destroy)(struct HardDiskFactory *this, struct HardDisk* hardDisk);
};// 构造函数
void HardDiskFactory(struct HardDiskFactory *this);// 析构函数
void _HardDiskFactory(struct HardDiskFactory *this);#endif

hard_disk_factory.c:

#include "hard_disk_factory.h"
#include "seagate_hard_disk.h"
#include "toshiba_hard_disk.h"
#include "stdio.h"
#include "stdlib.h"struct HardDisk *Create(struct HardDiskFactory *this, enum HARD_DISK_SUPPLIER_E supplier) 
{switch (supplier) {case HARD_DISK_SUPPLIER_SEAGATE:{struct SeagateHardDisk *seagateHardDisk = NULL;if ((seagateHardDisk = malloc(sizeof(struct SeagateHardDisk))) == NULL) {printf("fail in malloc\n");return NULL;}SeagateHardDisk(seagateHardDisk);return (struct HardDisk *)seagateHardDisk;}case HARD_DISK_SUPPLIER_TOSHIBA:{struct ToshibaHardDisk *toshibaHardDisk = NULL;if ((toshibaHardDisk = malloc(sizeof(struct ToshibaHardDisk))) == NULL) {printf("fail in malloc\n");return NULL;}ToshibaHardDisk(toshibaHardDisk);return (struct HardDisk *)toshibaHardDisk;}default:printf("未知的供应商\n");return NULL;}
}void Destroy(struct HardDiskFactory *this, struct HardDisk* hardDisk)
{if (hardDisk != NULL) {free(hardDisk);}
}// 构造函数
void HardDiskFactory(struct HardDiskFactory *this)
{this->Create = Create;this->Destroy = Destroy;
}// 析构函数
void _HardDiskFactory(struct HardDiskFactory *this)
{this->Create = NULL;this->Destroy = NULL;
}

客户端代码示例:

#include "hard_disk.h"
#include "hard_disk_factory.h"
#include "stddef.h"void main()
{struct HardDisk *hardDisk = NULL;struct HardDiskFactory hardDiskFactory;HardDiskFactory(&hardDiskFactory);// 创建 seagate 硬盘对象hardDisk = hardDiskFactory.Create(&hardDiskFactory, HARD_DISK_SUPPLIER_SEAGATE);// 使用 seagate 硬盘对象hardDisk->Operation(hardDisk);  // 销毁 seagate 硬盘对象hardDiskFactory.Destroy(&hardDiskFactory, hardDisk);       // 创建 toshiba 硬盘对象hardDisk = hardDiskFactory.Create(&hardDiskFactory, HARD_DISK_SUPPLIER_TOSHIBA);// 使用 seagate 硬盘对象hardDisk->Operation(hardDisk);// 销毁 toshiba 硬盘对象hardDiskFactory.Destroy(&hardDiskFactory, hardDisk);    _HardDiskFactory(&hardDiskFactory);
}

客户端显示示例:

./hard_disk
这是 Seagate 硬盘
这是 Toshiba 硬盘

*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

942333dde4cc0812be3dbc01e28ca44d.png

b5c5234e195b9c35675b27e1bb0f58a9.gif

戳“阅读原文”我们一起进步

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

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

相关文章

grpc 流式传输_编写下载服务器。 第一部分:始终流式传输,永远不要完全保留在内存中...

grpc 流式传输下载各种文件(文本或二进制文件)是每个企业应用程序的生死攸关的事情。 PDF文档,附件,媒体,可执行文件,CSV,超大文件等。几乎每个应用程序迟早都必须提供某种形式的下载。 下载是通…

matlab plot errorbar,如何为MATLAB errorbar plot的点和垂直线设置不同的图例?

这建立在Jens Boldsen’s answer之上,它添加了以下内容:>可以旋转表示图例中错误栏的线条使其垂直,或保持默认的水平方向;>该行的末尾用短线“关闭”.该方法非常通用,因为它支持:>任意颜色,线型和标记作为错误栏的参数.请注意,实际条形图始终绘…

C语言 / C++基础面试知识大集合

点击蓝字关注我们相对而言,C语言和C相关的面试题比较少见,没有Java方向写的人那么多,这是一篇 C 语言与 C面试知识点总结的文章,个人感觉非常难得,希望能对大家有所帮助。const作用修饰变量,说明该变量不可…

input发送a.jax_Java REST JAX-RS 2.0 –如何处理日期,时间和时间戳记数据类型

input发送a.jax无论是X-Form-Urlencoded还是JSON HTTP发布到REST资源端点,对于与日期或时间相关的数据都没有特定的“数据类型”。 大多数开发人员会将这些数据发布为“字符串”,或者只是将它们转换为Unix时间戳值(例如1435061152&#xff09…

php中is_int用法,php – is_int()和ctype_digit()之间有区别吗?

如果参数是整数类型,is_int()返回true,ctype_digit()采用字符串参数,如果字符串中的所有字符都是数字,则返回true。例:┌──────────┬───────────┬────────────────┐│ │ is_…

jooq sql_jOOQ星期二:Vlad Mihalcea深入了解SQL和Hibernate

jooq sql欢迎来到jOOQ Tuesdays系列。 在本系列文章中,我们每隔一个月的第三个星期二发布一篇文章,从jOOQ的角度采访我们发现该行业令人兴奋的人。 这包括从事SQL,Java,开放源代码以及各种其他相关主题的人员。 我们很高兴在第三…

C语言灵魂拷问:++i 为比 i++效率高?

点击蓝字关注我们相信很多人遇到过这样的问题:printf("%d,%d",i,i);也纠结过这个问题,到底答案是什么。确没有一个参考的资料。唯一知道的是,几乎所有C语言教材都这么讲:i就是先使用i的值再使i自身加一,而i则…

HibernateNONSTRICT_READ_WRITE CacheConcurrencyStrategy如何工作

介绍 在我以前的文章中 ,我介绍了READ_ONLY CacheConcurrencyStrategy ,这是不可变实体图的显而易见的选择。 当高速缓存的数据可变时,我们需要使用读写高速缓存策略,本文将介绍NONSTRICT_READ_WRITE二级高速缓存的工作方式。 内…

502无法解析服务器标头_编写下载服务器。 第三部分:标头:内容长度和范围...

502无法解析服务器标头这次,我们将探索更多HTTP请求和响应标头,以改善下载服务器的实现: Content-length和Range 。 前者表示下载量很大,后者允许部分下载文件,或者从我们开始的地方失败后继续下载。 Content-length响…

支付宝pc支付php,laravel框架下的pc支付宝支付接入

Time: 14:22*/return [//pc配置pcconfig>[partner >2088302186611, //这里是你在成功申请支付宝接口后获取到的PID;key >sxevk9h1vekjlx4y12arl6pryrz111, //这里是你在成功申请支付宝接口后获取到的Keyseller_id >208830211, //就是partnersign_type &…

最全,面中率最高的C++经典面试题分享!

点击蓝字关注我们1.new、delete、malloc、free关系delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C/C语言的标准库函数,new/delete是C的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象…

mysql不同版本会覆盖吗,[mysql不同版本数据库同步]mysql数据库主从同步,master和slave上的mysql必须版本一样吗,如果不一样会有什么结果?...

在线QQ客服:1922638专业的SQL Server、MySQL数据库同步软件497950890Slave_SQL_Running: No mysql同步故障解决如果数据不同步可以尝试该资料mysql> show slave status\GSlave_IO_Running: YesSlave_SQL_Running: NoLast_Errno: 1062….Seconds_Behind_Master:NU…

不可变集合相比可变集合_简单的基准测试:不可变集合VS持久集合

不可变集合相比可变集合通常,您需要向集合中添加新元素。 因为您是一个优秀而谨慎的开发人员,所以您希望尽可能保持不变。 因此,向不可变集合中添加新元素将意味着您必须创建一个新的不可变集合,其中包含原始集合的所有元素以及新…

C++ 面试被问到的“左值引用和右值引用”

点击蓝字关注我们1.左值和右值在C11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。举个例子,int a bc, a 就是左值,其有变量名为a,通过&a可以…

php如何解释xml,PHP – 如何解析这个xml?

我正在尝试解析下面的XML,以便最终得到一个看起来像样本的数组……我很难弄清楚如何获取标签内部的属性以输出我想要的方式它…XML我想要的数组::注意添加的数组元素Array[cust] > Array[rid] > 999999[member_id] > 12345[lname] > Doe[fname] > John[address]…

jug java_架构大型企业Java项目–我的虚拟JUG会话

jug java昨天我很荣幸被邀请参加虚拟JUG 。 这是一个很大的荣誉,其原因有很多:首先,我是vJUG董事会的一员,其次,因为这是我第二次向这个对Java感兴趣的伟大团队做演讲。 受到邀请总是很高兴。 架构大型企业Java项目 过…

初学者宝典:C语言入门基础知识大全

点击蓝字关注我们01C语言程序的结构认识用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使小伙伴对c语言有个初步认识。例1:计算两个整数之和的c程序:#include main() {int a,b,sum; a20; /*定义变量a,b&a…

php怎么使用多个数据库,怎么在php项目中使用CI对多个数据库进行操作

怎么在php项目中使用CI对多个数据库进行操作发布时间:2020-12-19 16:57:21来源:亿速云阅读:87作者:Leah今天就跟大家聊聊有关怎么在php项目中使用CI对多个数据库进行操作,可能很多人都不太了解,为了让大家更…

qt如何捕获应用程序输出_企业应用程序中需要捕获的5大Java性能指标

qt如何捕获应用程序输出有兴趣了解如何使用AppDynamics捕获这些Java性能指标吗? 立即开始免费试用 ! 前几篇文章介绍了应用程序性能管理(APM),并指出了有效实施APM战略的挑战。 本文通过回顾五个顶级性能指标来构建这…

C语言入门笔记,推荐收藏!

点击蓝字关注我们C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进…