2311C++抽象工厂
1,为啥需要工厂设计模式?工厂设计模式可解决什么问题?
先看一下示例,多态示例.
#include <iostream>
using namespace std;
class Shape {
public:Shape() { }virtual void drawShape(){cout << "base draw shape" << endl;}
};
class Rectangular : public Shape {
public:Rectangular(){ }void drawShape (){cout << "draw rectangular" << endl;}
};
class Triangular : public Shape {
public:Triangular () { }void drawShape (){cout << "draw triangular" << endl;}
};
class Circle : public Shape {
public:Circle(){ }void drawShape (){cout << "draw circle" << endl;}
};
int main()
{Shape *rect = new Rectangular();rect->drawShape();delete rect;Shape *tri = new Triangular();tri->drawShape();delete tri;Shape *cir = new Circle();cir->drawShape();delete cir;/*这里添加许多形状...*/return 0;
}
上述代码示例很简单,想带多态,绘画矩形,三角形,圆等.思考一个问题:如果还要画菱形,椭圆等等.很容易出现N多子类继承基本Shape,main()中的会大量的new XXXX,导致很难维护和扩展代码.
这就是工厂对象设计模式解决的问题之一.
还有,基类并不知道具体要实例化哪一个具体的子类,具体实例化要延迟到继承类中.
2,工厂设计模式
工厂创建产品. 产品==>多子产品.
工厂设计模式结构图,该模式下,工厂基类知道如何实例化具体产品
工厂=>具体工厂(创建产品)方法
产品(操作)=>具体产品(操作).
工厂设计模式结构图,延迟到子类中具体实例化对象方法
基本要素:
(1)抽象产品Product;
(2)具体产品ConcreteProduct;
(3)抽象工厂Factory.
(4)具体的工厂ConcreteFactory
下面直接给出代码示例:
头文件
#include <iostream>
using namespace std;
class Computer {
public:Computer();virtual ~Computer() = 0;
private:
};
class DellComputer: public Computer {
public:~DellComputer();DellComputer();
private:
};
class AppleComputer : public Computer {
public:AppleComputer();~AppleComputer();
};
class Factory {
public:Factory();virtual ~Factory() = 0;virtual Computer *CreateComputer(const string &type) = 0;//
private:
//串类型;
};
class ConcreateFactory: public Factory {
public:~ConcreateFactory();ConcreateFactory();Computer *CreateComputer(const string &type);
};//main.cpp
#include "product.h"
#include <iostream>
using namespace std;
Computer::Computer()
{cout << "Computer()" << endl;
}
Computer::~Computer()
{cout << "~Computer()" << endl;
}
DellComputer::DellComputer()
{cout << "DellComputer()" << endl;
}
DellComputer::~DellComputer()
{cout << "~DellComputer()" << endl;
}
AppleComputer::AppleComputer()
{cout << "AppleComputer()" << endl;
}
AppleComputer::~AppleComputer()
{cout << "~AppleComputer()" << endl;
}
Factory::Factory()
{cout << "Factory()" << endl;
}
Factory::~Factory()
{cout << "~Factory()" << endl;
}
ConcreateFactory::ConcreateFactory()
{cout << "ConcreateFactory()" << endl;
}
ConcreateFactory::~ConcreateFactory()
{cout << "~ConcreateFactory()" << endl;
}
Computer *ConcreateFactory::CreateComputer(const string &type)
{if (type == "dell")return new DellComputer();else if (type == "apple")return new AppleComputer();elsethrow invalid_argument("Invalid argument");
}
int main()
{Factory *fac = new ConcreateFactory();Computer *dell = fac->CreateComputer("dell"); //制造`dell`电脑delete dell;Computer *apple = fac->CreateComputer("apple"); //制造苹果电脑delete apple;delete fac;return 0;
}
使用工厂类的好处是,可在工厂类中封装创建对象的逻辑,使代码更模块化和清晰.同时,工厂类可按需选择创建不同产品对象,客户代码只需与抽象产品类交互,而不需要了解具体产品类.
这样代码更灵活,且更容易扩展和修改.
3,抽象工厂设计模式
工厂模式仅局限于某一个类,有时候需要为一组相关或依赖的对象提供配套的接口.此时就需要抽象工厂模式了,其实抽象工厂模式跟工厂模式是一回事.
抽象工厂(创建A,创建B)
=>多个具体工厂(创建A,创建B)
抽象产品A=>具体A1,具体A2
抽象产品B=>具体B1,具体B2
抽象工厂设计模式结构图,抽象工厂设计模式就是工厂模式的扩展版.
假如要为生成的电脑装操作系统,假如Dell--->windows系统,Apple----->IOS系统,再来一个华为电脑,需要装鸿蒙系统等.
头文件
#include <iostream>
using namespace std;
class Computer {
public:Computer();virtual ~Computer() = 0;
private:
};
class DellComputer: public Computer {
public:~DellComputer();DellComputer();
private:
};
class OS {
public:OS();virtual ~OS() = 0;
};
class WindowsOS : public OS {
public:WindowsOS();~WindowsOS();
};
class Factory {
public:Factory();virtual ~Factory() = 0;virtual Computer *CreateComputer() = 0;virtual OS *CreateOS() = 0;
private:
//串类型;
};
class ConcreateFactory: public Factory {
public:~ConcreateFactory();ConcreateFactory();Computer *CreateComputer();OS *CreateOS();
};
//main.cpp
#include "product.h"
#include <iostream>
using namespace std;
Computer::Computer()
{cout << "Computer()" << endl;
}
Computer::~Computer()
{cout << "~Computer()" << endl;
}
DellComputer::DellComputer()
{cout << "DellComputer()" << endl;
}
DellComputer::~DellComputer()
{cout << "~DellComputer()" << endl;
}
OS::OS()
{cout << "OS()" << endl;
}
OS::~OS()
{cout << "~OS()" << endl;
}
WindowsOS::WindowsOS()
{cout << "WindowsOS()" << endl;
}
WindowsOS::~WindowsOS()
{cout << "~WindowsOS()" << endl;
}
Factory::Factory()
{cout << "Factory()" << endl;
}
Factory::~Factory()
{cout << "~Factory()" << endl;
}
ConcreateFactory::ConcreateFactory()
{cout << "ConcreateFactory()" << endl;
}
ConcreateFactory::~ConcreateFactory()
{cout << "~ConcreateFactory()" << endl;
}
Computer *ConcreateFactory::CreateComputer()
{return new DellComputer();
}
OS *ConcreateFactory::CreateOS()
{return new WindowsOS();
}
int main()
{Factory *fac = new ConcreateFactory();Computer *dell = fac->CreateComputer();OS *os = fac->CreateOS();delete dell;delete os;delete fac;return 0;
}
相关文章:
2311C++抽象工厂
1,为啥需要工厂设计模式?工厂设计模式可解决什么问题? 先看一下示例,多态示例. #include <iostream> using namespace std; class Shape { public:Shape() { }virtual void drawShape(){cout << "base draw shape" << endl;} }; class Rectang…...
Lavarel定时任务的使用
系统为window 执行命令(执行一次命令只会根据当前时间运行一次定时任务) php artisan schedule:run创建一个任务类(在Jobs文件夹下面) <?phpnamespace App\Jobs;use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contract…...
Java开发者的网络安全指南(二)
目录 一、加密和数据保护 二、身份验证和授权 三、Web应用程序安全 四、安全编码实践 五、网络防火墙和入侵检测系统 六、日志和监视 七、漏洞管理 八、安全教育和培训 九、结论 介绍: 简要说明网络安全的重要性和为什么Java开发者需要关注它。 一、加密…...
Python基础学习016__UnitTest
# UnitTest是python自带的一个单元测试框架,不需要额外安装 # 也是自动化脚本执行框架,使用UnitTest来管理,运行多个框架 # 为什么使用:能够组织多个用例去执行.提供了丰富的断言方法,能够生成测试报告 # 核心要素: # Testcase:测试用例:这个测试用例是UnitTest的组成部分,不是…...
一物一码需求,标签制作功能轻松解决
许多行业存在为人员、物品、设备等做一物一码标签的需求,可使用草料标签制作功能。直接选择标签样式,填入数据,即可批量生成标签,还可批量排版,更易落地。还可保存标签样式,后续多次复用样式,批…...
【Linux】七、基础IO
预备知识 文件 属性(本质上也是数据)内容; 文件的所有操作大致有两种,对内容的操作,和对属性的操作; 文件在磁盘中放置,磁盘是硬件,只有操作系统可以真正的访问磁盘;C\C…...
Elasticsearch语法之Term query不区分大小写
设置关键词是否区分大小写 说明:case_insensitive是term的可选参数,默认为false,表示关键词区分大小写,设置为true表示关键词不区分大小写。该参数在7.10.0开始有效 需求:分别使用关键词"iphone"和"I…...
远程管理SSH服务
一、搭建SSH服务 1、关闭防火墙与SELinux # 关闭firewalld防火墙 # 临时关闭 systemctl stop firewalld # 关闭开机自启动 systemctl disable firewalld # 关闭selinux # 临时关闭 setenforce 0 # 修改配置文件 永久关闭 vim /etc/selinux/config SELINUXdisabled 2、配置…...
Linux 实现原理 — NUMA 多核架构中的多线程调度开销与性能优化
前言 NOTE:本文中所指 “线程” 均为可执行调度单元 Kernel Thread。 NUMA 体系结构 NUMA(Non-Uniform Memory Access,非一致性存储器访问)的设计理念是将 CPU 和 Main Memory 进行分区自治(Local NUMA node&#x…...
Oracle锁处理
背景: 随着数据库版本不断迭代更新, v$session 视图的内容越来越丰富,可以直接使用blocking_session、blocking_instance、final_blocking_instance和final_blocking_session字段进行定位。对于锁层次的排查可以重复查询v$session来确定&am…...
持续集成交付CICD:安装Jenkins Slave(从节点)
目录 一、实验 1.安装Jenkins Slave(从节点) 二、问题 1.salve节点启动jenkins报错 2.终止命令行后jenkins从节点状态不在线 一、实验 1.安装Jenkins Slave(从节点) (1)查看jenkins版本 Version 2.…...
Dart(一):Dart入门
Dart入门 Dart安装创建项目安装依赖(以http为例)依赖库查询地址添加依赖编写运行示例 dart常用命令引用核心库、自定义库、第三方库数据类型Numbers (int, double)Strings (String)Booleans (bool)Lists (List)Maps (Map)Sets (Set)Null (null)Records (…...
[动态规划] (十一) 简单多状态 LeetCode 面试题17.16.按摩师 和 198.打家劫舍
[动态规划] (十一) 简单多状态: LeetCode 面试题17.16.按摩师 和 198.打家劫舍 文章目录 [动态规划] (十一) 简单多状态: LeetCode 面试题17.16.按摩师 和 198.打家劫舍题目分析题目解析状态表示状态转移方程初始化和填表顺序 代码实现按摩师打家劫舍 总结 注:本题与…...
【EI会议投稿】第三届计算机、人工智能与控制工程国际学术会议 (CAICE 2024)
The 3rd International Conference on Computer, Artificial Intelligence and Control Engineering (CAICE 2024) 第三届计算机、人工智能与控制工程国际学术会议 第三届计算机、人工智能与控制工程国际学术会议(CAICE 2024)将于2024年1月26-28日在西…...
python 之 列表推导式
文章目录 基本结构示例 1:将列表中的元素乘以 2 添加条件判断示例 2:筛选出偶数并加倍 嵌套列表推导式示例 3:生成九九乘法表 使用条件表达式示例 4:根据条件返回不同的值 镶嵌使用详细介绍基本结构示例生成二维数组多重筛选和操作…...
【左程云算法全讲2】链表、栈、队列、递归、哈希表和有序表
系列综述: 💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考…...
SQL第三次上机作业
1.查询与王利就读同一专业学生的借书证号和姓名 SELECT Lno,Rname FROM Reader WHERE Dept(SELECT DeptFROM ReaderWHERE Rname王利)2.查询比希望出版社出版的所有图书价格都高的图书信息 SELECT * FROM Book WHERE Price>(SELECT MAX(Price)FROM BookWHERE Press希望出版…...
前端事件案例补充
目录 定时器示例 搜索框示例 省市联动 定时器示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><meta name"viewport" content"widthdevice-width, init…...
3.8 Android eBPF HelloWorld调试(二)
写在前面 我们开发eBPF程序的初衷就是再不改动内核的情况下,将内核监控数据传递给到用户态;像应用进程开发一样开发内核监控程序。 Android开机的时候eBPF程序被加载器加载到内核中,但此时它并没有被附加到内核函数上去,也就是ebpf程序并不会执行,我们可以理解为,它仅仅被…...
xss如何快速提取cookies
<script>alert(111)</script> <img srcx onerroralert(document.cookie)>测试一下baidu的xss <script>alert(111)</script><img srcx οnerrοralert(document.cookie)>...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
