设计模式-建造者模式(Builder Pattern)

一、建造者模式说明

        建造者模式(Builder Pattern)是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

在建造者模式中,通常涉及以下几个角色:

产品(Product)

  • 产品是要构建的复杂对象,包含多个部件。
  • 产品通常是由多个部件组成的复杂对象,建造者模式的目标就是创建这个复杂对象。

抽象建造者(Builder)

  • 抽象建造者定义了创建产品各个部件的抽象接口。
  • 抽象建造者中通常包含多个方法,用于构建产品的各个部件,例如构建引擎、构建轮胎、构建座椅等。
  • 它可以是一个抽象类或接口。

具体建造者(Concrete Builder)

  • 具体建造者实现了抽象建造者接口,负责具体构建产品的各个部件。
  • 每个具体建造者类对应一个特定的产品类型,并定义了具体构建该产品的过程。
  • 具体建造者类通常包含私有成员变量用于保存构建过程中的临时状态,并提供方法来构建不同部件。

指挥者(Director)

  • 指挥者负责调用具体建造者的方法来构建产品。
  • 指挥者知道构建产品的具体步骤和顺序,但不知道产品的具体细节。
  • 指挥者根据客户端的需求调用具体建造者的方法,将产品的构建过程与表示分离。

二、建造者模式样例

#include <iostream>
#include <string>// 产品类
class Product {
public:void setPartA(const std::string& partA) {partA_ = partA;}void setPartB(const std::string& partB) {partB_ = partB;}void setPartC(const std::string& partC) {partC_ = partC;}void show() const {std::cout << "Product parts: " << partA_ << ", " << partB_ << ", " << partC_ << std::endl;}private:std::string partA_;std::string partB_;std::string partC_;
};// 抽象建造者类
class Builder {
public:virtual ~Builder() {}virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product getResult() = 0;
};// 具体建造者类A
class ConcreteBuilderA : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderA");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderA");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderA");}Product getResult() override {return product_;}private:Product product_;
};// 具体建造者类B
class ConcreteBuilderB : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderB");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderB");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderB");}Product getResult() override {return product_;}private:Product product_;
};// 指挥者类
class Director {
public:void construct(Builder& builder) {builder.buildPartA();builder.buildPartB();builder.buildPartC();}
};int main() {Director director;ConcreteBuilderA builderA;ConcreteBuilderB builderB;// 构建产品Astd::cout << "Product A:" << std::endl;director.construct(builderA);Product productA = builderA.getResult();productA.show();// 构建产品Bstd::cout << "\nProduct B:" << std::endl;director.construct(builderB);Product productB = builderB.getResult();productB.show();return 0;
}

三、建造者模式的场景

以下是一些适用建造者模式的具体场景:

        游戏角色创建器:在游戏中,玩家可以选择不同的角色并自定义其外观、能力和装备。建造者模式可以用于创建角色的建造器,每个具体建造者负责构建不同类型的角色,而指挥者负责组装角色的各个部件,最终创建出完整的角色对象。

        文档生成器:在文档生成器中,可能需要创建不同类型的文档,例如简历、报告、新闻稿等。建造者模式可以用于创建文档的建造器,每个具体建造者负责构建不同类型的文档,而指挥者负责组装文档的各个部件,最终生成所需的文档对象。

        电脑组装器:在电脑组装器中,用户可以选择不同的硬件配置和外设,并自定义其性能和功能。建造者模式可以用于创建电脑的建造器,每个具体建造者负责构建不同配置的电脑,而指挥者负责组装电脑的各个部件,最终组装成用户所需的电脑。

        汽车定制器:在汽车定制器中,用户可以选择不同的汽车型号、颜色、配置和附件。建造者模式可以用于创建汽车的建造器,每个具体建造者负责构建不同配置的汽车,而指挥者负责组装汽车的各个部件,最终定制成用户所需的汽车。

        食品套餐订购系统:在食品套餐订购系统中,用户可以选择不同的食品套餐、主食、配菜和饮料。建造者模式可以用于创建食品套餐的建造器,每个具体建造者负责构建不同套餐的各个部件,而指挥者负责组装套餐的各个部件,最终生成用户所需的套餐对象。

四、建造者模式优缺点

建造者模式具有以下优点和缺点:

优点:

        分离构建过程和表示:建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示,提高了系统的灵活性。

        隐藏构建细节:建造者模式将对象的构建过程封装起来,只向客户端暴露一个简单的构建接口,客户端不需要关心对象的构建细节,降低了客户端与具体构建过程的耦合度。

        更加精细地控制构建过程:建造者模式可以让客户端按照需要灵活地指定构建顺序和选择构建部件,可以更加精细地控制对象的构建过程,满足不同的需求。

        增加对象的可复用性:由于建造者模式将对象的构建过程封装起来,可以在不改变原有代码的情况下,通过新增具体建造者类来创建新的对象表示,提高了对象的可复用性。

        增加系统的扩展性:由于建造者模式将构建过程和表示分离,新增具体建造者类或修改指挥者类不会影响其他部分的代码,增加了系统的扩展性。

缺点:

        增加系统复杂度:建造者模式引入了多个角色和类,增加了系统的复杂度,可能会导致代码量增加,不利于理解和维护。

        不适用于对象较简单的情况:当对象的构建过程比较简单,或者对象的内部结构比较稳定时,使用建造者模式可能会显得繁琐,不适合使用。

        不利于组装顺序的灵活性:建造者模式将构建过程固化在建造者类中,可能会限制对象组装顺序的灵活性,如果需要改变组装顺序,则需要修改建造者类或指挥者类。

        可能会产生多余的对象:由于建造者模式将构建过程和表示分离,可能会导致在构建对象过程中产生多余的对象,增加了系统的资源消耗。

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

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

相关文章

多业务场景下对于redis分布式锁的一些思考

现在让你写一个Redis分布式锁 大概率你会先写一个框架 public Boolean setIfAbsent(String key, Object value,Long timeout) {try {return Boolean.TRUE.equals(objectRedisTemplate.opsForValue().setIfAbsent(key, value,timeout,TimeUnit.SECONDS));} catch (Exception e) …

2024开年,手机厂商革了自己的命

文&#xff5c;刘俊宏 编&#xff5c;王一粟 2024开年&#xff0c;AI终端的号角已经由手机行业吹响。 OPPO春节期间就没闲着&#xff0c;首席产品官刘作虎在大年三十就迫不及待地宣布&#xff0c;OPPO正式进入AI手机时代。随后在开年后就紧急召开了AI战略发布会&#xff0c;…

【Antd】Form 表单获取不到 Input 的值

文章目录 今天遇到了一个奇怪的bug&#xff0c;Form表单中的Input组件的值&#xff0c;不能被Form获取&#xff0c;导致输入了内容&#xff0c;但是表单提交的时候值为undefined 报错代码 import { Button, Form, Input } from antd; import React from react;const App: Rea…

GaussDB SQL调优:建立合适的索引

背景 GaussDB是华为公司倾力打造的自研企业级分布式关系型数据库&#xff0c;该产品具备企业级复杂事务混合负载能力&#xff0c;同时支持优异的分布式事务&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000扩展能力&#xff0c;PB级海量存储等企业级数据库…

SQL中为什么不要使用1=1

最近看几个老项目的SQL条件中使用了11&#xff0c;想想自己也曾经这样写过&#xff0c;略有感触&#xff0c;特别拿出来说道说道。 编写SQL语句就像炒菜&#xff0c;每一种调料的使用都可能会影响菜品的最终味道&#xff0c;每一个SQL条件的加入也可能会影响查询的执行效率。那…

昨天Google发布了最新的开源模型Gemma,今天我来体验一下

前言 看看以前写的文章&#xff0c;业余搞人工智能还是很早之前的事情了&#xff0c;之前为了高工资&#xff0c;一直想从事人工智能相关的工作都没有实现。现在终于可以安静地系统地学习一下了。也是一边学习一边写博客记录吧。 昨天Google发布了最新的开源模型Gemma&#xf…

电商数据采集的几个标准

面对体量巨大的电商数据&#xff0c;很多品牌会选择对自己有用的数据进行分析&#xff0c;比如在控价过程中&#xff0c;需要对商品的价格数据进行监测&#xff0c;或者是需要做数据分析时&#xff0c;则需要采集到商品的价格、销量、评价量、标题、店铺名等信息&#xff0c;数…

Unity中.Net与Mono的关系

什么是.NET .NET是一个开发框架&#xff0c;它遵循并采用CIL(Common Intermediate Language)和CLR(Common Language Runtime)两种约定&#xff0c; CIL标准为一种编译标准&#xff1a;将不同编程语言&#xff08;C#, JS, VB等&#xff09;使用各自的编译器&#xff0c;按照统…

JavaScript 原始值和引用值在变量复制时的异同

相比于其他语言&#xff0c;JavaScript 中的变量可谓独树一帜。正如 ECMA-262 所规定的&#xff0c;JavaScript 变量是松散类型的&#xff0c;而且变量不过就是特定时间点一个特定值的名称而已。由于没有规则定义变量必须包含什么数据类型&#xff0c;变量的值和数据类型在脚本…

mysql.service is not a native service, redirecting to systemd-sysv-install

字面意思&#xff1a;mysql.service不是本机服务&#xff0c;正在重定向到systemd sysv安装 在CentOS上使用Systemd管理MySQL服务的具体步骤如下&#xff1a; 1、创建MySQL服务单元文件&#xff1a; 首先&#xff0c;你需要创建一个Systemd服务单元文件&#xff0c;以便Syste…

【Python笔记-设计模式】原型模式

一、说明 原型模式是一种创建型设计模式&#xff0c; 用于创建重复的对象&#xff0c;同时又能保证性能。 使一个原型实例指定了要创建的对象的种类&#xff0c;并且通过拷贝这个原型来创建新的对象。 (一) 解决问题 主要解决了对象的创建与复制过程中的性能问题。主要针对…

redhawk:使用ipf文件反标instance power

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 往期文章链接: Redhawk:Input Data Preparation 使用ptpx和redhawk报告功耗时差别总是很大,如果需要反标top/block的功耗值可以在gsr文件中使用BLOCK_POWER_FOR_SCALING的命令

Verilog刷题笔记35

题目&#xff1a; Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel0 should select in[0], sel1 selects bits in[1], sel2 selects bits in[2], etc. 解法&#xff1a; module top_module( input [255:…

Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用

Lison <dreamlison163.com>, v1.0.0, 2023.10.20 Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用 文章目录 Spring Cloud Alibaba-05-Gateway网关-02-断言(Predicate)使用通过时间匹配通过 Cookie 匹配通过 Header 匹配通过 Host 匹配通过请求方式匹配通…

C# CAD2016 cass10宗地Xdata数据写入

一、 查看cass10写入信息 C# Cad2016二次开发获取XData信息&#xff08;二&#xff09; 一共有81条数据 XData value: QHDM XData value: 121321 XData value: SOUTH XData value: 300000 XData value: 141121JC10720 XData value: 权利人 XData value: 0702 XData value: YB…

2.居中方式总结

居中方式总结 经典真题 怎么让一个 div 水平垂直居中 盒子居中 首先题目问到了如何进行居中&#xff0c;那么居中肯定分 2 个方向&#xff0c;一个是水平方向&#xff0c;一个是垂直方向。 水平方向居中 水平方向居中很简单&#xff0c;有 2 种常见的方式&#xff1a; 设…

java面试题之mybatis篇

什么是ORM&#xff1f; ORM&#xff08;Object/Relational Mapping&#xff09;即对象关系映射&#xff0c;是一种数据持久化技术。它在对象模型和关系型数据库直接建立起对应关系&#xff0c;并且提供一种机制&#xff0c;通过JavaBean对象去操作数据库表的数据。 MyBatis通过…

MATLAB练习题:randperm函数的练习题

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili MATLAB中有一个非常有用的函数&#xff1a;randperm函数&…

华为算法题 go语言或者ptython

1 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返…

如何进行高性能架构的设计

一、前端优化 减少请求次数页面静态化边缘计算 增加缓存控制&#xff1a;请求头 减少图像请求次数&#xff1a;多张图片变成 一张。 减少脚本的请求次数&#xff1a;css和js压缩&#xff0c;将多个文件压缩成一个文件。 二、页面静态化 三、边缘计算 后端优化 从三个方面进…