C++设计模式|创建型 4.建造者模式

news2024/10/6 8:31:37

1.什么是建造者模式?

建造者模式(也被成为生成器模式),是一种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,而建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义一个抽象的接口具体的构建过程由实现了这些接口的具体建造者类来完成同时有一个指导者类负责协调建造者的工作,按照一定的顺序或逻辑来执行构建步骤,最终生成产品。

举个例子,假如我们要创建一个计算机对象,计算机由很多组件组成,例如 CPU、内存、硬盘、显卡等。每个组件可能有不同的型号、配置和制造,这个时候计算机就可以被视为一个复杂对象,构建过程相对复杂,而我们使用建造者模式将计算机的构建过程封装在一个具体的建造者类中,而指导者类则负责指导构建的步骤和顺序。每个具体的建造者类可以负责构建不同型号或配置的计算机,客户端代码可以通过选择不同的建造者来创建不同类型的计算机,这样就可以根据需要构建不同表示的复杂对象,更加灵活。

2.建造者模式的基本结构

  • 产品Product:被构建的复杂对象, 包含多个组成部分。
  • 抽象建造者Builder: 定义构建产品各个部分的抽象接口和一个返回复杂产品的方法getResult
  • 具体建造者Concrete Builder实现抽象建造者接口,构建产品的各个组成部分,并提供一个方法返回最终的产品。
  • 指导者Director调用具体建造者的方法,按照一定的顺序或逻辑来构建产品。

在客户端中,通过指导者来构建产品,而并不和具体建造者进行直接的交互。 

3.建造者模式的大致流程

  1. 定义产品类:产品类应该包含多个组成部分,这些部分的属性和方法构成了产品的接口。
  2. 定义抽象建造者接口:创建一个接口,包含构建产品各个部分的抽象方法。这些方法通常用于设置产品的各个属性。
  3. 创建具体建造者:实现抽象建造者接口,构建具体的产品。
  4. 定义Director类: 指导者类来控制构建产品的顺序和步骤。
  5. 客户端使用建造者模式:在客户端中创建【具体建造者对象】和【指导者对象】,通过指导者来构建产品。

4.建造者模式的使用场景 

使用建造者模式有下面几处优点:

  • 使用建造者模式可以将一个复杂对象的构建与其表示分离,通过将构建复杂对象的过程抽象出来,可以使客户端代码与具体的构建过程解耦

  • 同样的构建过程可以创建不同的表示,可以有多个具体的建造者(相互独立),可以更加灵活地创建不同组合的对象。

建造者模式适用于复杂对象的创建,当对象构建过程相对复杂时可以考虑使用建造者模式,但是当产品的构建过程发生变化时,可能需要同时修改指导类和建造者类,这就使得重构变得相对困难(缺点)。

5.C++实现建造者模式

【设计模式专题之建造者模式】4. 自行车加工 (kamacoder.com)icon-default.png?t=N7T8https://kamacoder.com/problempage.php?pid=1084

题目描述:

小明家新开了一家自行车工厂,用于使用自行车配件(车架 frame车轮 tires )进行组装定制不同的自行车,包括山地车和公路车。

山地车使用的是Aluminum Frame(铝制车架)和 Knobby Tires(可抓地轮胎),公路车使用的是 Carbon Frame (碳车架)和 Slim Tries。

现在它收到了一笔订单,要求定制一批自行车,请你使用【建造者模式】告诉小明这笔订单需要使用那些自行车配置吧。

输入描述:

输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示订单的数量。 

接下来的 N 行,每行输入一个字符串,字符串表示客户的自行车需求。

字符串可以包含关键词 "mountain" 或 "road",表示客户需要山地自行车或公路自行车。例如:

3
mountain
road
mountain

输出描述:

对于每笔订单,输出该订单定制的自行车配置。例如:

Aluminum Frame Knobby Tires
Carbon Frame Slim Tires
Aluminum Frame Knobby Tires

在本例中:产品为自行车,所以可以有两个具体建造者山地车建造者公路车建造者

按照本文所述的建造者模式的大致流程,写出C++代码如下:

#include<iostream>
#include<string>
using namespace std;

//按照建造者模式的流程来实现
//1、定义产品类,要包含产品的属性和设置方法
class Bike{
    //友元函数加左移运算符重载,用来链式输出自定义数据类型的内容。
    //通常类内只做友元函数的声明,具体实现要写在类外
    friend ostream& operator<<(ostream & out, const Bike & bike);
private:
    //自行车的属性有车架frame和车轮tires
    string frame;
    string tires;
public:   
    //定义接口方法,为属性设置具体的形式
    void setFrame(const string& frame){
        this->frame = frame;
    }
    
    void setTires(const string& tires){
        this->tires = tires;
    }
    

};
//
ostream& operator<<(ostream & out, const Bike & bike)
{
    out<<bike.frame<<" "<<bike.tires;
    return out;
}


//2.定义抽象建造者接口:创建一个接口,包含构建产品各个部分的抽象方法
class AbstractBikeBuilder{
public:
    //定义构建自行车的抽象接口
   virtual void bulidFrame() = 0;
   virtual void buildTires() = 0;
   virtual Bike&  getResult() = 0;
};


//3.定义具体建造者
//3.1 定义具体山地车建造者
class MountainBikeBuilder : public AbstractBikeBuilder{
private:
    Bike bike;
public:
    void bulidFrame() override {
        bike.setFrame("Aluminum Frame");
    
    }
    
    void buildTires() override{
        bike.setTires("Knobby Tires");
    }
    
    Bike&  getResult() override{
        return bike;
    }
    
};


//3.2 定义具体公路车建造者
class RoadBikeBuilder : public AbstractBikeBuilder{
private:
    Bike bike;
public:
    void bulidFrame() override {
        bike.setFrame("Carbon Frame");
    
    }
    
    void buildTires() override{
        bike.setTires("Slim Tires");
    }
    
    Bike&  getResult() override{
        return bike;
    }
    
};


//4.定义指导者类来控制构建产品的顺序和步骤
class BikeDirector{
public:
//需要通过指导者类来调用建造者
    Bike& construct(AbstractBikeBuilder &builder){
        builder.bulidFrame();
        builder.buildTires();
        return builder.getResult();
    }
};

int main()
{
    int N;
    cin>>N;
    
    
    for(int i=0; i < N; i++)
    {
        string bikeType;
        cin>>bikeType;
        
        
        AbstractBikeBuilder *builder;
        //根据输入,创建不同的具体建造者
        if(bikeType == "mountain"){
            builder = new MountainBikeBuilder();
        }
        else if(bikeType == "road"){
            builder = new RoadBikeBuilder();
        }

        //指导者通过具体建造者来指导产品生产
        BikeDirector director;
        //接口传入具体的建造者指针,该函数内部通过建造者指针调用生产过程
        Bike bike = director.construct(*builder);
        //《《运算符的重载实现了自定义数据的输出
        cout<<bike<<endl;
        
        delete builder;
    }
    
    return 0;
}

 

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

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

相关文章

OpenHarmony图形处理库—pyclipper [GN编译]

简介 pyclipper是图形处理库&#xff0c;用于剪裁和偏移直线和多边形。 下载安装 直接在OpenHarmony-SIG仓中搜索pyclipper并下载。 使用说明 以OpenHarmony 3.1 Beta的rk3568版本为例 将下载的pyclipper库代码存在以下路径&#xff1a;./third_party/pyclipper 修改添加依…

Java 算法篇-深入了解 BF 与 KMP 算法

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 BF 算法概述 1.1 BF 算法实际使用 2.0 KMP 算法概述 2.1 KMP 算法实际使用 2.2 相比于 BF 算法实现&#xff0c;KMP 算法的重要思想 2.3 为什么要这样设计&#x…

ATFX汇市:日元贬值导致进口物价走高,日央行或有二次加息计划

消息面&数据面&#xff1a; 日本央行行长植田和男表示&#xff0c;弱势日元可能影响通胀趋势&#xff0c;如果这样可能导致政策转变。意思是说&#xff0c;随着日元汇率逼近160.00&#xff0c;日元贬值对进口物价的影响越来越明显。如果日元继续保持贬值态势&#xff0c;日…

【Java】文件大小转换工具类(B,KB,MB,G,TB,PB)

说明 使用方法&#xff1a;FileMemoryUtil.prettyByteSize(35871)&#xff0c;参数为字节个数 返回结果&#xff1a;保留一位小数的自适应结果&#xff08;例如&#xff1a;4.1KB&#xff09;。可以留意在浏览器上下载的文件&#xff0c;会根据文件大小展示不同的单位&#xff…

腾讯面试准备-2024.3.25

腾讯面试准备-2024.3.25 腾讯面试准备-2024.3.25自我介绍C11/14/17新特性C11新特性C14新特性C17新特性 struct和class的区别进程状态现代的流媒体通信协议栈流媒体协议详解extern "C"程序从编译到执行的过程进程、线程、协程进程线程协程 如何实现一个信号与槽系统&a…

【强化学习的数学原理-赵世钰】课程笔记(十)Actor-Critic 方法

目录 一.最简单的 actor-critic&#xff08;QAC&#xff09;&#xff1a;The simplest actor-critic (QAC) 二.Advantage actor-critic (A2C) 三.Off-policy actor-critic 方法 四. Deterministic actor critic(DPG) Actor-Critic 方法把基于 value 的方法&#xff0c;特别…

maven3.9的settings.xml 内容学习

settings.xml 文件介绍 settings.xml 是 Maven 的配置文件&#xff0c;它允许你自定义 Maven 的行为&#xff0c;比如设置仓库、代理、认证信息等。在 Maven 3.9 中&#xff0c;settings.xml 的结构和内容可能与之前的版本相似&#xff0c;但可能会有一些小的改进或变化。下面…

【码农教程】手把手教你Mockito的使用

一、前期准备&#xff5e; 1、准备工作 <!--mockito依赖--> <dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>2.7.19</version><scope>test</scope> </dependenc…

NASM中的-f选项

2024年4月19日&#xff0c;周五下午 -f选项 在 NASM 中&#xff0c;-f 选项用于指定输出格式或目标文件格式。这个选项允许你告诉 NASM 将汇编代码编译成特定格式的目标文件&#xff0c;以便与特定的操作系统或环境兼容。下面是 -f 选项的一些常见用法和参数&#xff1a; -f …

excel表格怎么设置密码?excel文件加密的两个方法

一、加密码的原理​ Excel加密码的原理主要基于加密算法和密钥管理。当用户为Excel文件或工作表设置密码时&#xff0c;Excel会采用一种加密算法对文件或工作表进行加密处理。这种加密算法通常是对称加密算法&#xff0c;如AES(高级加密标准)或DES(数据加密标准)。 二&#x…

iframe和 blob实现JS,CSS,HTML直接当前页预览

先贴效果图&#xff1a; <template><div><div class"aaa"></div><div class"btn-run" click"tres">运行</div></div></template><script>import { mapState } from vuex;export default …

C++之类和对象三

目录 拷贝构造函数 定义铺垫 浅拷贝 深拷贝 总结 拷贝构造函数 那在创建对象时&#xff0c;可否创建一个与一个对象一某一样的新对象呢&#xff1f; 定义铺垫 构造函数&#xff1a;只有单个形参&#xff0c;该形参是对本类类型对象的引用(一般常用const修饰)&#xff0c…

软考-系统集成项目管理中级--项目质量管理(输入输出很重要!!!本章占分较高,着重复习)

本章历年考题分值统计 本章重点常考知识点汇总清单 5、成本效益分析法:对每个质量活动进行成本效益分析&#xff0c;就是要比较其可能的成本与预期的效益。达到质量要求的主要效益包括减少返工、提高生产率、降低成本、提升干系人满意度及提升赢利能力。(掌握)17下64考题 本章…

IDEA配置Maven环境

黑马程序员JavaWeb开发教程 文章目录 如果当前有已经打开项目的话&#xff0c;File -> Close Project 到以下页面之后选择 Customize -> All settings… 配置maven的安装目录&#xff0c;maven的配置文件&#xff0c;maven的本地仓库&#xff08;修改完成之后一定要先…

DRF 序列化类保存save源码

【七】序列化保存save源码 【1】介绍 无论是创建还是修改数据&#xff0c;都需要执行save方法&#xff0c;再前面的使用中都没有再里面添加过参数 其实save中可以给额外参数比如.save(timedatetime.datetime.now())这个需要模型表中有time的字段&#xff0c;结果就是将当前时…

【YOLOv5】利用Kaggle的GPU训练(运行)yolov5模型(项目)

文章目录 &#xff08;一&#xff09;下载YOLOv5源码&#xff08;二&#xff09;修改YOLOv5源码1、修改输出文件的保存路径&#xff08;适应Kaggle的输出路径&#xff09;2、在data文件夹中新建一个yaml文件3、在 train.py 中修改data路径4、指定训练的轮数5、修改模型配置文件…

C语言 | Leetcode C语言题解之第38题外观数列

题目&#xff1a; 题解&#xff1a; class Solution { public:string countAndSay(int n) {string s "1", ans "1";for (int i 2; i < n; i) {ans "";for (int j 0; j < int(s.size()); ) {int k j;while(k < int(s.size()) &am…

使用yolov8 进行实例分割训练

1、基于windows 的ISAM标注 直接下载安装包&#xff0c;解压后即可使用 链接&#xff1a;https://pan.baidu.com/s/1u_6jk-7sj4CUK1DC0fDEXQ 提取码&#xff1a;c780 2、标注结果转yolo格式 通过ISAM标注后的json文件路径 原始json格式如下&#xff1a; ISAM.json 转 yolo.…

[阅读笔记1][GPT-3]Language Models are Few-Shot Learners

首先讲一下GPT3这篇论文&#xff0c;文章标题是语言模型是小样本学习者&#xff0c;openai于2020年发表的。 这篇是在GPT2的基础上写的&#xff0c;由于GPT2还存在一些局限&#xff0c;这篇对之前的GPT2进行了一些完善。GPT2提出了多任务学习&#xff0c;也就是可以零样本地用在…

深入剖析跨境电商平台风控机制,探索测评安全与稳定的秘诀

在跨境电商测评市场鱼龙混杂的当下&#xff0c;测评过程中可能隐藏的陷阱保持高度警觉。多年的测评经验告诉我们&#xff0c;选择一个适合的测评系统对于项目的成功至关重要。近年来&#xff0c;测评技术如雨后春笋般涌现&#xff0c;市场上涌现出众多测评系统&#xff0c;覆盖…