当前位置: 首页 > news >正文

设计模式(七)创建者模式之建造者模式

这里写目录标题

  • 概述
  • 需求
  • 需求类图
    • Bike
    • Builder
    • MobikeBuilder
    • OfoBuilder
    • Director
    • Client
    • Client
    • 优缺点
    • 使用场景
  • 模式扩展
    • Computer
    • Client
    • 创建者模式对比
      • 工厂方法模式VS建造者模式
      • 抽象工厂模式VS建造者模式
  • 总结

概述

  • 建造者模式又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同属性的对象
  • 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,不需要知道内部的具体构建细节(如用户在选购汽车的时候,只需要选择好方向盘、轮胎、发动机类型,不需要知道零件是怎么制造出来的)
  • 在这里插入图片描述
    例如需要把这些的配件组装成一个主机。第一步安装CPU、第二步安装风扇、第三步安装内存条…
    建造者模式注重于组装。

需求

创建共享单车

生产自行车是一个复杂的过程,它包含了车架,车座等组件的生产。而车架又有碳纤维,铝合金等材质的,车座有橡胶,真皮等材质。对于自行车的生产就可以使用建造者模式。

这里Bike是产品,包含车架,车座等组件;Builder是抽象建造者,MobikeBuilder和OfoBuilder是具体的建造者;Director是指挥者。类图如下:

需求类图

实例

Bike

package com.lx.design.creator.builder;/*** TODO 添加描述** @author lx* @date 2024/6/18 23:11* 自行车类*/
public class Bike {private String frame;private String seat;public String getFrame() {return frame;}public void setFrame(String frame) {this.frame = frame;}public String getSeat() {return seat;}public void setSeat(String seat) {this.seat = seat;}
}

Builder

package com.lx.design.creator.builder;/*** TODO 添加描述** @author lx* @date 2024/6/18 23:12*/
public abstract class Builder {protected Bike bike = new Bike();public abstract void buildFrame();public abstract void buildSeat();public abstract Bike createBike();
}

MobikeBuilder

package com.lx.design.creator.builder;/**
* TODO 添加描述
*
* @author lx
* @date 2024/6/18 23:13
* 摩拜单车
*/
public class MobikeBuilder extends Builder {@Overridepublic void buildFrame() {bike.setFrame("铝合金车架");}@Overridepublic void buildSeat() {bike.setSeat("真皮车座");}@Overridepublic Bike createBike() {return bike;}
}

OfoBuilder

package com.lx.design.creator.builder;/**
* TODO 添加描述
*
* @author lx
* @date 2024/6/18 23:13
*/
public class OfoBuilder extends Builder{@Overridepublic void buildFrame() {bike.setFrame("碳纤维车架");}@Overridepublic void buildSeat() {bike.setSeat("橡胶车座");}@Overridepublic Bike createBike() {return bike;}
}

Director

package com.lx.design.creator.builder;/**
* TODO 添加描述
*
* @author lx
* @date 2024/6/18 23:15
*/
public class Director {private Builder mBuilder;public Director(Builder builder) {mBuilder = builder;}public Bike construct() {mBuilder.buildFrame();mBuilder.buildSeat();return mBuilder.createBike();}
}

Client

package com.lx.design.creator.builder;/**
* TODO 添加描述
*
* @author lx
* @date 2024/6/18 23:16
*/
public class Client {public static void main(String[] args) {//创建建造者MobikeBuilder mobikeBuilder = new MobikeBuilder();//复制建造者Director director = new Director(mobikeBuilder);//建造者构建自行车Bike bike = director.construct();System.out.println(bike.getFrame());System.out.println(bike.getSeat());}}

注意:

上面示例是 Builder模式的常规用法,指挥者类 Director 在建造者模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把指挥者类和抽象建造者进行结合

// 抽象 builder 类
public abstract class Builder {protected Bike mBike = new Bike();public abstract void buildFrame();public abstract void buildSeat();public abstract Bike createBike();//添加以下代码public Bike construct() {this.buildFrame();this.BuildSeat();return this.createBike();}
}

Client

public static void main(String[] args) {Bike bike = new MobikeBuilder().construct();System.out.println(bike.getFrame());System.out.println(bike.getSeat());}

优缺点

优点:

  • 建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在指挥者类中对整体而言可以取得比较好的稳定性。
  • 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  • 建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。符合开闭原则。

缺点:

造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。

使用场景

建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。

  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

模式扩展

建造者模式除了上面的用途外,在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构。

Computer

package com.lx.design.creator.builder.three;/*** TODO 添加描述** @author lx* @date 2024/6/19 16:27*/
public class Computer {private String cpu;private String wifi;// 私有构造方法,只能通过Builder来创建对象private Computer(ComputerBuilder builder) {this.cpu=   builder.cpu;this.wifi=   builder.wifi;}public String getCpu() {return cpu;}public void setCpu(String cpu) {this.cpu = cpu;}public String getWifi() {return wifi;}public void setWifi(String wifi) {this.wifi = wifi;}public static class ComputerBuilder {private String cpu;private String wifi;public String getCpu() {return cpu;}public ComputerBuilder setCpu(String cpu) {this.cpu = cpu;return this;}public String getWifi() {return wifi;}public ComputerBuilder setWifi(String wifi) {this.wifi = wifi;return this;}public Computer build(){return new Computer(this);}}
}

Client

package com.lx.design.creator.builder.three;/*** TODO 添加描述** @author lx* @date 2024/6/19 16:33*/
public class Client {public static void main(String[] args) {Computer build = new Computer.ComputerBuilder().setCpu("cpu").setWifi("wifi").build();System.out.println(build.getWifi());System.out.println(build.getCpu());}
}

创建者模式对比

工厂方法模式VS建造者模式

工厂方法模式注重的是整体对象的创建方式;而建造者模式注重的是部件构建的过程,意在通过一步一步地精确构造创建出一个复杂的对象。

我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。建造者注重于步骤、组装。工厂方法注重于结果。

抽象工厂模式VS建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。

建造者模式则是要求按照指定的组件或者步骤建造产品,它的主要目的是通过组装零配件而产生一个新产品

如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车

总结

优点:

分步构建对象:

  • 建造者模式允许你按照步骤构建对象,通过链式调用或者在每个步骤中设置属性来完成。这样的方式比直接构造器构建更加灵活和直观,特别是当对象的构建过程比较复杂或者有多个可选参数时,尤为有效。

隐藏复杂构建过程:

  • 建造者模式将复杂对象的构建过程封装在一个独立的建造者类中,使得客户端代码不必知道具体的构建细节。客户端只需指定需要的配置和选项,而无需关心对象是如何一步步构建的。

提高代码复用性:

  • 可以通过建造者模式构建不同配置的对象,从而提高代码的复用性。同一个建造者可以用于构建多个不同表现形式的对象,只需改变建造者的配置参数即可。

便于控制构建过程:

  • 建造者模式可以在构建过程中逐步验证和设置对象的属性,可以在每个步骤中进行逻辑处理或者条件判断,从而更好地控制对象的构建过程。
    遵循单一职责原则:
  • 建造者模式将对象的构建和表示分离,每个具体建造者负责构建特定类型的对象。这有助于遵循单一职责原则,每个类专注于一个特定的构建任务。

缺点
增加了代码量:

  • 引入建造者模式会增加代码量,因为需要创建一个具体建造者类、可能的多个产品类以及指挥者(如果有的话)。这在简单对象的情况下可能显得繁琐。

对象构建过程更加复杂:

  • 如果对象相对简单,并且构建过程不太可能变化,使用建造者模式可能会显得过于复杂和冗余。此时直接使用构造函数或者工厂方法可能更为简单和直接。

不易于应对分步构建的变化:

  • 如果需要频繁修改对象的构建过程或者构建步骤,建造者模式可能会变得笨重,因为每次改动都需要修改建造者的逻辑或者添加新的建造者类。

可能导致对象不一致:

  • 如果在构建过程中缺少必要的约束或者验证逻辑,可能会导致最终构建的对象不符合预期,尤其是当对象的构建过程涉及多个步骤和条件时。

相关文章:

设计模式(七)创建者模式之建造者模式

这里写目录标题 概述需求需求类图BikeBuilderMobikeBuilderOfoBuilderDirectorClientClient优缺点使用场景 模式扩展ComputerClient创建者模式对比工厂方法模式VS建造者模式抽象工厂模式VS建造者模式 总结 概述 建造者模式又叫生成器模式,是一种对象构建模式。它可…...

# class中的__call__方法解析

class中的__call__方法解析 文章目录 class中的__call__方法解析1. 为什么要有call,什么情况下用call?1.1 为什么要有 __call__ 方法1.2 没有 __call__ 方法是否可以1.3 使用 __call__ 方法的典型场景1.3.1 示例1:简单函数对象1.3.2 示例2&am…...

React逻辑复用的方式都有哪些

在日常开发中,能够优雅的复用组件和逻辑,是优秀开发者的职责。在react中,复用逻辑的方式有很多,可以适用于不同的业务场景。今天说三个比较有代表性的,Render Props、HOC、Hooks Render Props 创建一个接受函数作为其…...

【LinuxC语言】线程重入

文章目录 前言线程重入是什么线程重入实现示例代码总结前言 在并发编程中,我们经常需要处理多个线程同时访问和修改共享资源的问题。这可能会导致数据竞争和状态不一致,从而使程序的行为变得不可预测。为了解决这个问题,我们引入了一种称为“线程重入”的机制。线程重入,或…...

【Streamlit学习笔记】Streamlit-ECharts箱型图添加均值和最值label

Streamlit-ECharts Streamlit-ECharts是一个Streamlit组件,用于在Python应用程序中展示ECharts图表。ECharts是一个由百度开发的JavaScript数据可视化库Apache ECharts 安装模块库 pip install streamlitpip install streamlit-echarts绘制箱型图展示 在基础箱型…...

Docker镜像仓库:存储与分发Docker镜像的中央仓库

探索Docker镜像仓库:存储与分发Docker镜像的中央仓库 如果你是Docker的新手,或者已经在使用Docker但还不太了解Docker镜像仓库,那么这篇博客将是你的最佳指南。我们将从基础概念开始,逐步深入,帮助你全面掌握Docker注…...

FreeRTOS必考面试题及参考答案

什么是RTOS?FreeRTOS是什么?它主要应用于哪些领域? RTOS,即实时操作系统(Real-Time Operating System),是一种专门为实时应用程序设计的操作系统,它强调的是对外部事件的快速响应和可预测性。实时系统通常要求在严格的时限内完成关键任务,因此RTOS具备优先级调度、确…...

面试题2:从浏览器输入一个URL,到最终展示前端页面这一过程,会发生什么?

这是一个高频的面试题目。 题目答案是开放性的,一般以后端开发的角度回答。 当地址栏输入一个 URL 后: 一、首先会进行 DNS 域名解析 DNS 域名解析:网络上的设备都是通过 IP 地址,作为身份标识的。但是由于点分十进制的 IP 地址 …...

<Rust><iced><resvg>基于rust使用iced构建GUI实例:使用resvg库实现svg转png

前言 本文是使用rust库resvg来将svg图片转为png图片。 环境配置 系统:windows 平台:visual studio code 语言:rust 库:resvg 代码分析 resvg是一个基于rust的svg渲染库,其官方地址: An SVG rendering li…...

面试突击:Java 中的泛型

本文已收录于:https://github.com/danmuking/all-in-one(持续更新) 前言 哈喽,大家好,我是 DanMu。今天想和大家聊聊 Java 中的泛型。 什么是泛型? Java 泛型(Generics) 是 JDK 5…...

3_2、MFC常用控件用法:组合框、滚动条和图片控件

MFC控件用法 1、组合框1.1 简介1.2 创建CComboBox类的主要成员函数 1.3 实例 2、滚动条控件2.1 简介2.2 创建CScrollBar类的主要成员函数 2.3 实例 3、图片控件3.1 简介3.2 创建图片控件静态加载图片图片控件动态加载图片 1、组合框 1.1 简介 组合框其实就是把一个编辑框和一…...

如何使用gprof对程序进行性能分析

如何使用gprof对程序进行性能分析 目录 1 gprof概述 2 gprof原理简述 3 gprof使用 3.1 gprof使用简述 3.2 gprof使用示例 4 小结 1 gprof概述 gprof 是 一个 GNU 的程序性能分析工具,可以用于分析C\C程序的执行性能。gprof工具可以统计出各个函数的调用次数、执…...

四川汇聚荣科技有限公司靠谱吗?

在如今这个信息爆炸的时代,了解一家公司是否靠谱对于消费者和合作伙伴来说至关重要。四川汇聚荣科技有限公司作为一家位于中国西部地区的企业,自然也受到了人们的关注。那么,这家公司究竟如何呢?接下来,我们将从多个角度进行深入…...

可灵王炸更新,图生视频、视频续写,最长可达3分钟!Runway 不香了 ...

现在视频大模型有多卷? Runway 刚在6月17号 发布Gen3 ,坐上王座没几天; 可灵就在6月21日中午,重新夺回了王座!发布了图生视频功能,视频续写功能! 一张图概括: 二师兄和团队老师第一…...

oracle中使用临时表GLOBAL TEMPORARY TABLE

需要在存储过程中返回一个临时结果集,这个结果集又是多个语句通过循环查询出来的,这时候就想到了将结果插入到临时表中,然后返回临时表的数据的思路,于是有了以下操作: 1.创建临时表 -- Create table create global …...

Gradio入门—快速开始

目录 安装构建您的第一个演示分享您的演示核心 Gradio 课程聊天机器人gr.ChatInterface自定义演示gr.BlocksGradio Python 和 JavaScript 生态系统 Gradio 是一个开源 Python 软件包,可让您快速为机器学习模型、API 或任何任意 Python 函数构建演示或 Web 应用程序。…...

AOP应用之系统操作日志

本文演示下如何使用AOP&#xff0c;去实现系统操作日志功能。 实现步骤 引入AOP包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.6.6</version></de…...

海外云手机自动化管理,高效省力解决方案

不论是企业还是个人&#xff0c;对于海外社媒的营销都是需要自动化管理的&#xff0c;因为自动化管理不仅省时省力&#xff0c;而且还节约成本&#xff1b; 海外云手机的自动化管理意味着什么&#xff1f;那就是企业无需再投入大量的人力和时间去逐一操作和监控每一台设备。 通…...

后仿真中的 《specify/endspecify block》之(5)使用specify进行时序仿真

前面我们学习了specify...endspecify 具体是什么东西。今天,我们使用specify block 中定义的延时,来进行一次仿真。看看到底是背后如何运转的呢。 一 基本例子 一个用 specify 指定延迟的与门逻辑描述如下: module and_gate(output Z,input A, B);assign Z = A & …...

win10/11磁盘管理

win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的&#xff0c;比如如下&#xff1a; 如果需要吧这个磁盘进行分解&#xff0c;你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话&#xff0c;因为压缩出来的卷和C盘好像是不相邻的&#xff08;我之前做过&…...

【昇思初学入门】第四天打卡

数据变换Transforms 心得体会 MindSpore提供了丰富的数据变换工具&#xff0c;针对图像数据可以使用如Rescale、Normalize和HWC2CHW等&#xff0c;且使用Compose类允许我们定义一个变换序列&#xff0c;并将它们作为一个整体应用到数据上。 composed transforms.Compose([v…...

禁用/屏蔽 Chrome 默认快捷键

Chrome 有一些内置的快捷键&#xff0c;但是它并没有像其他软件一样提供管理快捷键的界面。在某些时候&#xff0c;当我们因为个人需求希望禁用 Chrome 某些快捷键时&#xff0c;又无从下手。 好在有开发者开发了 Chrome 插件&#xff0c;可以禁用 Chrome 快捷键的插件&#x…...

移动端+PC端应用模式的智慧城管综合执法办案平台源码,案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析

城市管理综合执法管理平台实现执法办案、业务全流程在线办理&#xff0c;依托移动端PC端的“两端”应用模式&#xff0c;保障能够通过信息化手段进行日常的执法办案工作&#xff0c;强化执法监督功能。提供了案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析等功能&a…...

AI音乐大模型时代:版权归属与创意产业的新生长点

AI在创造还是毁掉音乐&#xff1f; 简介&#xff1a;最近一个月&#xff0c;轮番上线的音乐大模型&#xff0c;一举将素人生产音乐的门槛降到了最低&#xff0c;并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后&#xff0c;AI产品的版权归属于谁&#xff0c;创意产业要…...

C++函数作为参数

C++函数作为参数 在C++中,函数作为另一个函数的参数是非常常见的做法,特别是在处理回调函数和泛型编程时。我们展示了如何在C++中将函数作为参数传递给另一个函数,包括普通函数、std::function 和 std::bind、lambda表达式以及类成员函数。每种方法都有其独特的优势,可以根…...

考前刷题练手感(北航期末往年数据结构编程题)

本次因为是考前一天极速刷题&#xff0c;所以没有讲解&#xff0c;若有问题可私信。 目录 一、 查找同时空人员二、 老鼠回家-无回路三、函数调⽤关系四、东二食堂模拟五、栈帧 一、 查找同时空人员 【问题描述】 假设一共有6个手机基站&#xff0c;都具有记录手机连接基站状…...

Android记录9--实现转盘效果

自定义View /2013.10.16_TurnPlate_Demo/src/com/wwj/turnplate/TurnPlateView.java package com.wwj.turnplate; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; im…...

【Oracle APEX开发小技巧1】转换类型实现显示小数点前的 0 以 及常见类型转换

在 apex 交互式式网格中&#xff0c;有一数值类型为 NUMBER&#xff0c;保留小数点后两位的项&#xff0c;在 展示时小数点前的 0 不显示。 效果如下&#xff1a; 转换前&#xff1a; m.WEIGHT_COEFFICIENT 解决方案&#xff1a; 将 NUMBER&#xff08;20&#xff0c;2&#xf…...

GRIT论文阅读笔记

一篇试图统一生成任务和编码任务的工作&#xff0c;就是把只能完成生成任务的GPT改成既能生成又能encode。思路其实很简单&#xff0c;就是在输入的时候添加instruction tokens来指引模型做representation还是generation&#xff0c;然后各自算损失。representation任务用的是d…...

1980python个性化电影推荐管理系统mysql数据库Django结构layUI布局elasticsearch存储计算机软件工程网页

一、源码特点 python Django个性化电影推荐管理系统是一套完善的web设计系统mysql数据库 利用elasticsearch存储浏览数据 &#xff0c;对理解python编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 开发环境pycharm…...

网站建设技术经理岗位职责/如何自己建设网站

一、百度地图 百度地图JavaScript API是一套由JavaScript语言编写的应用程序接口&#xff0c;可帮助您在网站中构建功能丰富、交互性强的地图应用&#xff0c;支持PC端和移动端基于浏览器的地图应用开发&#xff0c;且支持HTML5特性的地图开发。该套API免费对外开放。自v1.5版本…...

谷歌怎么把两个网站做反链/荥阳网络推广公司

在设计中&#xff0c;布局是一个重要的环节。布局结果的好坏将直接影响布线的效果&#xff0c;因此可以这样认为&#xff0c;合理的布局是PCB设计成功的第一步。 尤其是预布局&#xff0c;是思考整个电路板&#xff0c;信号流向、散热、结构等架构的过程。如果预布局是失败的&…...

怎么做家政的网站/企业网站的类型

python安装dlib库报错问题及解决方法发布时间&#xff1a;2020-09-01 06:02:57...

qq业务代理网站建设/最新百度快速排名技术

题目描述给一个链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;输出null。解题思路及代码方法一&#xff1a;哈希法基本思路就是遍历单链表的每个结点&#xff0c;将之前没有被访问的结点存入 set&#xff0c;如果某个结点被…...

网站建设的关键/搜索引擎营销案例分析

Oracle导出空&#xff08;无数据&#xff09;表 exp name/pass fileD:/backup.dmp logD:/backup.log;其中table_1中有数据&#xff0c;table_2中没有数据&#xff1b;由于 ORACLE 11g中有个新特性&#xff0c;当表无数据时&#xff0c;不分配segment&#xff0c;以节省空间。所…...

国外域名的网站/最佳搜索引擎

curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载&#xff0c;所以是综合传输工具&#xff0c;但按传统&#xff0c;习惯称curl为下载工具。作为一款强力工具&#xff0c;curl支持包括HTTP、HTTPS、ftp等众多协议&#xff0c;还支持POST、cooki…...