C++的工厂模式与建造者模式连用

设计模式

  • 工厂模式与建造者模式连用
    • 工厂模式
    • 建造者模式
    • 具体使用

工厂模式与建造者模式连用

工厂模式

工厂模式:是一种常用的设计模式,它属于创建型设计模式,旨在将对象的创建过程与使用过程分离,以实现解耦和灵活性。工厂模式通过提供一个公共的接口来创建对象,而不直接使用new操作符,从而降低了系统的耦合度,使得代码更加易于维护和扩展。

工厂模式可以分为三种类型:简单工厂模式、工厂方法模式和抽象工厂模式。简单工厂模式由一个工厂类根据传入的参数动态决定创建哪一个产品类的实例。工厂方法模式则定义了一个创建对象的接口,由子类决定实例化哪一个类。抽象工厂模式则更为复杂,它允许生产一系列相关或独立的产品,而不需要关心具体产品的创建过程。

工厂模式的优点包括:
降低了耦合度,使得调用者只需要关心产品的接口,而不必了解具体的实现细节。
提高了扩展性,当需要增加新的产品时,只需要扩展相应的工厂类或具体产品类,而不需要修改已有的代码。屏蔽了产品的具体实现,使得系统更加灵活和可维护。
工厂模式也存在一些缺点:
当需要增加新的产品时,可能需要增加相应的具体类和对象来实现工厂逻辑,这可能会增加系统的复杂度。
在某些情况下,使用工厂模式可能会引入额外的类和对象,增加了系统的开销。
适用场景:
当一个对象拥有很多子类时,可以使用工厂模式来创建对象,避免直接使用new操作符。
当创建某个对象时需要进行许多额外的操作时,工厂模式可以隐藏这些操作,使得客户端代码更加简洁。
当系统后期需要经常扩展时,工厂模式可以将对象实例化的任务交给实现类完成,提高系统的可扩展性。

首先定义抽象工厂接口和具体工厂类。抽象工厂用于创建不同类型的汽车组件

// 汽车组件接口
class Engine {
public:virtual std::string getType() const = 0;virtual ~Engine() = default;
};class Wheel {
public:virtual std::string getType() const = 0;virtual ~Wheel() = default;
};// 具体的汽车组件
class SUVEngine : public Engine {
public:std::string getType() const override {return "SUV Engine";}
};class SedanEngine : public Engine {
public:std::string getType() const override {return "Sedan Engine";}
};class SUVTire : public Wheel {
public:std::string getType() const override {return "SUV Tire";}
};class SedanTire : public Wheel {
public:std::string getType() const override {return "Sedan Tire";}
};// 抽象工厂接口
class CarFactory {
public:virtual std::unique_ptr<Engine> createEngine() const = 0;virtual std::unique_ptr<Wheel> createWheel() const = 0;virtual ~CarFactory() = default;
};// 具体工厂:SUV工厂
class SUVFactory : public CarFactory {
public:std::unique_ptr<Engine> createEngine() const override {return std::make_unique<SUVEngine>();}std::unique_ptr<Wheel> createWheel() const override {return std::make_unique<SUVTire>();}
};// 具体工厂:Sedan工厂
class SedanFactory : public CarFactory {
public:std::unique_ptr<Engine> createEngine() const override {return std::make_unique<SedanEngine>();}std::unique_ptr<Wheel> createWheel() const override {return std::make_unique<SedanTire>();}
};

建造者模式

建造者模式 (Builder Pattern) 属于创建型模式的一种, 主要用于将一个复杂对象的构建与它的表示分离, 向用户屏蔽复杂对象组成部分的创建细节。
在者模式中,有4个角色:
建造者(Builder):为创建一个产品对象的各个部件指定抽象接口。

具体建造者(ConcreteBuilder):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。

指挥者(Director):指挥并构造一个使用Builder接口的对象,负责和客户(Client)对话。

产品(Product):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

模式优点

  1. 用户只需要指定要建造的类型就可以得到它们,而具体的建造过程和细节不需要知道。
  2. 建造代码与表示相分离,如果要改变一个产品的内部表示,只要再定义一个新的具体的建造者就可以了。
  3. 建造过程由指挥者来控制,建造细节由一个抽象类来控制,对于实现建造细节的具体类来说,不会遗漏某一个步骤。

模式缺点

  1. 产品必须有共同点,范围有限制。
  2. 如内部变化复杂,会有很多的建造类

示意代码如下

// 产品类:汽车
class Car {
public:void setEngine(std::unique_ptr<Engine> eng) {engine = std::move(eng);}void setWheel(std::unique_ptr<Wheel> whl) {wheel = std::move(whl);}void show() const {if (engine) {std::cout << "Engine: " << engine->getType() << std::endl;}if (wheel) {std::cout << "Wheel: " << wheel->getType() << std::endl;}}private:std::unique_ptr<Engine> engine;std::unique_ptr<Wheel> wheel;
};// 建造者接口
class CarBuilder {
public:virtual void buildEngine() = 0;virtual void buildWheel() = 0;virtual std::unique_ptr<Car> getCar() = 0;virtual ~CarBuilder() = default;
};// 具体建造者
class ConcreteCarBuilder : public CarBuilder {
public:ConcreteCarBuilder(const CarFactory& factory) : factory(factory), car(std::make_unique<Car>()) {}void buildEngine() override {car->setEngine(factory.createEngine());}void buildWheel() override {car->setWheel(factory.createWheel());}std::unique_ptr<Car> getCar() override {return std::move(car);}private:const CarFactory& factory;std::unique_ptr<Car> car;
};
// 指导者类
class Director {
public:void setBuilder(CarBuilder* bldr) {builder = bldr;}void construct() {if (builder) {builder->buildEngine();builder->buildWheel();}}private:CarBuilder* builder = nullptr;
};

具体使用

int main() {// 创建具体的工厂SUVFactory suvFactory;SedanFactory sedanFactory;// 创建具体的建造者ConcreteCarBuilder suvBuilder(suvFactory);ConcreteCarBuilder sedanBuilder(sedanFactory);// 指导者Director director;// 构建SUVdirector.setBuilder(&suvBuilder);director.construct();std::unique_ptr<Car> suv = suvBuilder.getCar();std::cout << "Built a new SUV:\n";suv->show();// 构建Sedandirector.setBuilder(&sedanBuilder);director.construct();std::unique_ptr<Car> sedan = sedanBuilder.getCar();std::cout << "Built a new Sedan:\n";sedan->show();return 0;
}

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

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

相关文章

在Ubuntu 14.04上安装和配置SNMP守护程序和客户端的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 作为系统管理员的重要工作之一是收集关于服务器和基础设施的准确信息。有许多工具和选项可用于收集和处理这种类型的信息。其中许…

数据库期末复习知识点

A卷 1. 选择题(30) 2. 判断范式(10) 判断到第三范式 3. 程序填空(20) 4. 分析填空(15) 5. 写SQL(25) 5一题 恶性 B卷 1. 单选(30) 2. 填空 (20) 3. 程序填空(20) 4. 写SQL(30) 知识点 第一章 数据库管理系统(DBMS) 主要功能 数据定义功能 (DDL, 数据定义语言, …

linux 登录ftp报Received message too long 1416128883

在linux 登录ftp报Received message too long 1416128883 [rootlocalhost ~]# sftp oaftp172.20.xx.xx解决办法&#xff1a; [rootlocalhost ~]# usermod -s /bin/bash oaftp[rootlocalhost ~]# systemctl restart vsftpd.service[rootlocalhost ~]# sftp oaftp172.20.xx.xx完…

JavaWeb系列十六: jQuery初步入门

跟老韩-JavaScript开发利器之jQuery 1.1 原理示意图1.2 快速入门1.2 什么是jquery对象1.3 dom对象转jQuery对象1.4 jQuery对象转dom对象 jQuery是一个快速的, 简洁的javaScript库, 使用户能更方便地处理HTML, css, dom…提供方法, events, 选择器, 并且方便地为网站提供AJAX交互…

【ElasticSearch】ElasticSearch实战

初步检索 检索 ES 信息 1&#xff09;、GET /_cat/nodes&#xff1a;查看所有节点 127.0.0.1 44 83 1 0.01 0.01 0.00 dilm * 1b06a843b8e3 *代表主节点 2&#xff09;、GET /_cat/health&#xff1a;查看健康状况 1718265331 07:55:31 elasticsearch yellow 1 1 4 4 0 0…

ansible archive模块

用于创建归档文件的模块。它允许你在目标主机上创建tar、zip、gzip、bzip2、xz等类型的归档文件。解压使用unarchive模块。 path&#xff1a;要打包的源目录或文件的路径。&#xff08;可以是单个文件或目录&#xff0c;也可以是包含多个文件和目录的列表。&#xff09;dest&am…

告别单张OCR,Umi-OCR让你轻松实现批量识别!

大家好&#xff0c;今天我要给大家介绍一款强大的OCR识别软件——Umi-OCR。相信很多朋友都用过QQ、微信或天若OCR等应用来进行图片文字识别&#xff0c;但你是否遇到过需要批量识别图片文字时&#xff0c;这些软件却无法满足你的需求呢&#xff1f;今天&#xff0c;这个问题将迎…

LeetCode 算法:二叉树的中序遍历 c++

原题链接&#x1f517;&#xff1a;二叉树的中序遍历 难度&#xff1a;简单⭐️ 题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&…

Spring数据访问架构设计解析

一、Spring JDBC 数据访问 1、简化了jdbc操作&#xff0c;定义了模板类JdbcTemplate 2、提高开发效率&#xff0c;构建了嵌入式数据源EmbeddedDatabase 3、统一底层异常结构DataAccessException 二、Spring事物管理器 声明式事物&#xff0c;Aop原理简化开发 三、Spring …

go sync包(三) 读写锁(二)

读写锁 RWMutex 写锁 加锁 RWMetex 的写锁复用了 Mutex&#xff1a; // Lock locks rw for writing. // If the lock is already locked for reading or writing, // Lock blocks until the lock is available. func (rw *RWMutex) Lock() {if race.Enabled {_ rw.w.state…

Selenium 选择器定位元素方式详解

Selenium 选择器定位元素方式详解 在自动化测试中&#xff0c;定位网页元素是一个至关重要的步骤。Selenium 提供了多种选择器来帮助我们精确地找到页面上的元素。以下将详细介绍各种选择器的用法和区别&#xff0c;包括 ID、XPATH、LINK_TEXT、PARTIAL_LINK_TEXT、NAME、TAG_…

将Windows11右键菜单修改为Windows10风格

Windows11更新后&#xff0c;右键菜单很多功能隐藏起来了&#xff0c;使用时需要点击“显示更多选型”才能获取完整功能。为了能获得Windows10右键菜单丝滑的体验&#xff0c;我总结了以下方法。 方法一&#xff1a;控制台操作法 按住winR打开运行窗口 输入cmd&#xff0c;…

区间问题——905. 区间选点

目录 区间问题 定义 运用情况 注意事项 解题思路 AcWing 905. 区间选点 题目描述 运行代码 代码思路 改进思路 其它代码 代码思路 区间问题 定义 区间通常是指一个连续的范围&#xff0c;可以用数轴上的一段来表示。 运用情况 在数学中广泛用于表示变量的取值范…

未系安全带智能监测摄像机

未系安全带智能监测摄像机在现代安全管理中发挥着至关重要的作用。这些先进设备不仅仅是简单的监视工具&#xff0c;更是通过整合高级技术来提升工作效率和安全性&#xff0c;特别是在需要高度警惕的作业环境中尤为突出。 首先&#xff0c;这些智能监测摄像机配备了精准的视觉识…

SOLIDWORKS专业版2024价格

SOLIDWORKS Professional 专业版&#xff0c;带有 ECAD/MCAD 协作、自动成本估算、协作功能、设计和工程图检查、复杂的零部件库以及高级真实感渲染。 1. ECAD/MCAD协作&#xff1a;SOLIDWORKS专业版提供了强大的ECAD/MCAD协作功能&#xff0c;使得设计团队可以更高效地进行跨…

HTML(23)——垂直对齐方式

垂直对齐方式 属性名&#xff1a;vertical-align 属性值效果baseline基线对齐(默认)top顶部对齐middle居中对齐bottom底部对齐 默认情况下浏览器对行内块&#xff0c;行内标签都按文字处理&#xff0c;默认基线对齐 导致图片看起来会偏上&#xff0c;文字偏下。 示例&#…

帝国cms定时审核并更新的方法

比如你网站采集了成千上万篇文章,不可能一下子全部放出来的,所以为了模拟人工发布,那么就需要定时审核发布文章内容,本文内容核心解决了更加个性化的逼真模拟人工更新网站内容。 第一:首先要满足你的表中有未审核的数据 第二:到http://bbs.phome.net/showthread-31-19616…

谷歌浏览器截图

一 右击&#xff0c;然后点击检查&#xff1b; 二 然后ctrlshiftp,运行命令&#xff1b; 三 3.1搜索截图&#xff1a; 如果你设置为中文&#xff0c;搜索截图&#xff0c;选择你想要的截图类型&#xff1b; 如果你是在英文情况下&#xff1a; 输入capture full size 来过滤…

【Redis】如何保证缓存和数据库的一致性

目录 背景问题思路 三个经典的缓存模式Cache-Aside读缓存写缓存为什么是删除旧缓存而不是更新旧缓存&#xff1f;为什么不先删除旧的缓存&#xff0c;然后再更新数据库&#xff1f; 延迟双删如何确保原子性 Read-Through/Write-ThroughRead-ThroughWrite-Through Write Behind …

【九】【QT开发应用】WebRTC的sigslot源码和使用WebRTC的sigslot使用编写信号槽

WebRTC&#xff08;Web Real-Time Communication&#xff09; 是一个开源项目&#xff0c;提供实时通信能力&#xff0c;广泛应用于视频、音频和数据传输。在WebRTC的实现中&#xff0c;sigslot库用于信号和槽机制&#xff0c;以实现事件驱动的编程模型。 WebRTC的sigslot部分…