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

08.哲说建造者模式(Builder Pattern)

“The odds that we’re in ‘base reality’ is one in billions.” —— Elon Musk
这段话出自马斯克在2016年的一次演讲,“人类活在真实世界的几率,可能不到十亿分之一”。此言一出,可谓一石激起千层浪。有人嘲讽马斯克是“语不惊人死不休”,也有人对他的言论深信不疑,更多的人则是把这种言论当作茶余饭后消遣的谈资。在这里插入图片描述
笔者对于 “世界是否真的真实” 这一问题的结果并不狂热,但我对于马斯克说出这句话的时间点很感兴趣,我可以帮大家捋一下前后的时间线。
2016年,ChatGPT诞生,而马斯克正是OpenAI的联合创办人之一
2017年,ChatGPT正式推出
2018年,ChatGPT开始全面发展,在社区活跃度直线上升
2019年,OpenAI从非营利性组织转型为“利润上限(caped-profit)”公司后,马斯克离开
2020年至今,ChatGPT逐渐火爆出圈,可以说改变人们的生活方式去日不远

在这里插入图片描述
微妙吗?“日心说” 源于计算结果,马斯克的话是否也源于即有结果的合理推测呢?这个话题可能每个人都会有自己的看法。
“天下万物生于有,有生于无。”——《道德经·第四十章》


一言

建造者模式是一步步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建他们而不需要知道内部具体的构建细节。


概述

“天下万物生于有,有生于无”。如果现在我告诉你,你可以创建一个世界,你是一个造物主,但是你要把自己藏起来,不能让这个世界的小生命知道你的存在,你会以什么样的逻辑来设计第一个模型?
有人说,我要信“码”由缰,懒得装;有人说,我要挖空细节演好上帝。
这其实就是设计模式有趣的地方,它松散无骨,语气平和,不按它的来这个世界的太阳照常升起,但按它的要求做,这个世界会和谐的像假的一样。
这一次,我想让阅读我博客的你和我一起演一次“造物主”,从神的角度,俯视设计模式中的“建造者模式”。

一个看似无关紧要且过分晦涩的概念

建造者模式(Builder Pattern) 又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现 (属性) 的对象。


创世纪

好了,上帝们,我们开始。
我们假定创造一个世界的过程是:创建星球环境,播种生命,注入意识。但是每个世界肯定有不同的差别(作为上帝,我们不可能只创建了一个世界对不?)。那么自然有的世界的星球环境是单星结构,而有的是三体结构(很熟悉吧);生命形态肯定也不尽相同,碳基生物还是硅基生物或者其它神奇的生命体;意识就更是千变万化了。
在这里插入图片描述


信“码”由缰的上帝

如果我是那个只想快速完成KPI,不考虑运行后果的上帝,我可能会这样设计。
在这里插入图片描述

代码实现

一个抽象

public abstract class AbstractHouse {//基础环境public abstract void buildEarth();//创造生命public abstract void humanBeing();//意识觉醒public abstract void aware();//建造public void build(){buildEarth();humanBeing();aware();}
}

实现人类文明

public class HumanWorld extends AbstractHouse{@Overridepublic void buildEarth() {System.out.println("太阳系三号行星已构建");}@Overridepublic void humanBeing() {System.out.println("灵长类动物已生成");}@Overridepublic void aware() {System.out.println("人类意识觉醒,温良恭俭让");}
}

实现外星文明

public class ETWorld extends AbstractHouse{@Overridepublic void buildEarth() {System.out.println("猎户座九号行星已构建");}@Overridepublic void humanBeing() {System.out.println("硅基生物已生成");}@Overridepublic void aware() {System.out.println("异形意识觉醒,碾碎他们");}
}

经典反思

有什么问题?
优点自不必多说,两分钟的设计难度简单,易操作。
问题就是这个设计结构太简单了,上帝不会这么简单的去创建一个世界的。
没有任何的缓存层对象,程序可以说几乎没有可扩展和维护的空间。把产品(世界)和创建产品的过程(创世过程)完全封装在一起,耦合度太高了。

那么我们如何化腐朽为神奇呢?这就引出了建造者模式。


神之一手

先来了解下建造者模式的四个角色

  1. Product (产品角色) : 一个具体的产品对象;
  2. Builder (抽象建造者): 创建一个Product对象的各个部件指定的接口/抽象类;
  3. ConcreteBuilder (具体建造者):实现接口,构建和装配各个部件;
  4. Director (指挥者):构建一个Builder接口的对象,它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程;二是:负责控制产品对象的生产过程。

图解

在这里插入图片描述

代码

产品类

public class World{private String space;//环境private String alive;//生命private String aware;//意识//setter&getter
}

抽象建造者

public abstract class WorldBuilder {protected  World world = new World();//将建造的流程写好,抽象的方法public abstract void buildEarth();public abstract void humanBeing();public abstract void aware();//建造世界,将产品返回public World build(){return world;}
}

地球文明建造者

public class EarthBuilder extends WorldBuilder{@Overridepublic void buildEarth() {System.out.println("太阳系三号行星");world.setSpace("地球");}@Overridepublic void humanBeing() {System.out.println("地球生命");world.setAlive("人类");}@Overridepublic void aware() {System.out.println("地球人意识");world.setAware("温良恭俭让");}
}

外星文明建造者

public class ETBuilder extends WorldBuilder{@Overridepublic void buildEarth() {System.out.println("猎户座九号行星");world.setSpace("赛博坦");}@Overridepublic void humanBeing() {System.out.println("外星生命");world.setAlive("硅基生物");}@Overridepublic void aware() {System.out.println("外星人意识");world.setAware("活下去,撕碎他们");}
}

指挥者

public class WorldDirector {WorldBuilder worldBuilder = null; //方式1:构造器传入 worldBuilderpublic WorldDirector (WorldBuilder worldBuilder ) {this.worldBuilder = worldBuilder ;}//方式2:通过setter 传入 worldBuilderpublic void setWorldBuilder(WorldBuilder worldBuilder ) {this.worldBuilder = worldBuilder ;}//如何建造世界的流程,交给指挥者//创世public World constructWorld(){worldBuilder.buildEarth();worldBuilder.humanBeing();worldBuilder.aware();return worldBuilder.build();}
}

测试类

public class Client {public static void main(String[] args) {WorldDirector worldDirector = new WorldDirector (new EarthBuilder());World earth = worldDirector.constructWorld();worldDirector.setWorldBuilder(new ETBuilder());World et = worldDirector.constructWorld();System.out.println("地球人基本意识:"+earth.getAware());System.out.println("外星人基本意识:"+et.getAware());}
}

测试结果

在这里插入图片描述


Builder Pattern在JDK源码中的应用

其实设计模式离我们的日常开发非常近,建造者模式也不例外。比如StringBuilder,从名字看也差不多能猜到coder的思想和意图。
在这里插入图片描述
通过阅读Appendable、AbstractStringBuilder和StringBuilder的源码,我们会发现:

  • Appendable 接口定义了多个append方法(抽象方法),即Appendable 为抽象建造者,定义了抽象方法
  • AbstractStringBuilder 实现了 Appendable 接口方法,这里的AbstractstringBuilder 已经是建造者,只是不能实例化
  • StringBuilder 即充当了指挥者角色,同时充当了具体的建造者,建造方法的实现是由 AbstractStringBuilder 完成,而StringBuilder 继承了AbstractStringBuilder

客户端(使用程序)不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程系统扩展方便,这也符合此前我们强调过的“开闭原则”。建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,因此在这种情况下,要考虑选择建造者模式是不是真的是最优解。
其实可以着重理解一下Director的构造这部分,在我看来,Builder Pattern的巧妙之处就在于它优雅的将一颗“种子”丢到了一个星球上,在“种子”发芽之前我们无需关注这颗种子的大小、品相。“万物生于有,有生于无”。

相信能耐心读到这里的同学应该会有一种奇怪的感觉,建造者模式怎么有点类似于抽象工厂模式呢?

那么抽象工厂模式是什么?工厂模式又是什么?它们和建造者模式又有什么异同呢?卖个关子,明年(下周)讲。

预祝大家新年快乐哈~


关注我,共同进步,每周至少一更,来聊的不只是代码。——Wayne

相关文章:

08.哲说建造者模式(Builder Pattern)

“The odds that we’re in ‘base reality’ is one in billions.” —— Elon Musk 这段话出自马斯克在2016年的一次演讲,“人类活在真实世界的几率,可能不到十亿分之一”。此言一出,可谓一石激起千层浪。有人嘲讽马斯克是“语不惊人死不休…...

ubuntu18.04查询实时内存、CPU占用率命令

gnome-system-monitor效果就是下面这样:...

Python计算圆的面积

Python 计算圆的面积 圆的面积公式为 : 公式中 r 为圆的半径。 # 定义一个方法来计算圆的面积 def findArea(r): PI 3.142 return PI * (r*r) # 调用方法 r float( input("请输入圆的半径:") ) print( "圆的面积为 %.3f&qu…...

(Java企业 / 公司项目)Nacos的怎么搭建多环境配置?(含相关面试题)(二)

上一篇讲了一个单体服务中配置,传统的Nacos配置但是在微服务架构当中肯定都是多环境下配置,比如生产环境,dev测试环境等等。 第一种方式模拟开始: 首先展示在生产环境中nacos如何配置,在模块下新建一个配置文件&…...

DolphinScheduler实际应用

前言 最近公司新启动了一个项目,然后领导想用一下新技术,并且为公司提供多个大数据调度解决方案,我呢就根据领导要求调研了下当前的开源调度工具,最终决定采用DolphinScheduler, 因此研究了一下DolphinScheduler &…...

P10 RV1126推流项目——ffmpeg输出参数初始化

前言 从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ 🔥 推荐专栏2: 《Linux C应用编程(概念类)_C…...

正定矩阵在格密码中的应用(知识铺垫)

目录 一. 写在前面 二. 最小值点 三. 二次型结构 四. 正定与非正定讨论 4.1 对参数a的要求 4.2 对参数c的要求 4.3 对参数b的要求 五. 最小值,最大值与奇异值 5.1 正定型(positive definite) 5.2 负定型(negative defin…...

关于使用Selenium获取网页控制台的数据

背景: 需要获取网页的控制台的数据,如下图 在此文章将使用到 Pycharm 和 Selenium4 Pycharm安装 Selenium安装 from selenium import webdriver from selenium.webdriver.common.by import By import time# 创建浏览器对象 browser webdriver.Chro…...

vue2和vue3中的路由使用及传参方式

文章目录 vue2中使用路由Vue3 中使用路由路由传参方式 Vue 2 和 Vue 3 中的路由系统有很多相似之处,但也存在一些重要的区别。下面将分别介绍 Vue 2 和 Vue 3 中的路由使用方式,并了解下它们之间的不同之处。 vue2中使用路由 在 Vue 2 中,通…...

论文管理器

论文管理器 这个论文管理器仍然存在许多漏洞。目前,通过按照一些例行程序操作,它可以正常工作。我将在有时间的时候改进代码,提供详细说明,并添加新功能。当该管理器的代码进行优化后,我会上传到github上。 一个建立…...

postfix配置tls加密

1.编译安装 编译安装openss【卸载原有openssl,然后下载新的安装,因为postfix需要新版本openssl】编译安装postfix,下面这行命令 make -f Makefile.init makefiles CCARGS"-DHAS_MYSQL -I/www/server/mysql/include -DUSE_SASL_AUTH -I/usr/include…...

虚拟专线网络(IP-VPN)

虚拟专线网络(IP-VPN),因为它的安全性和可靠性。通过亚洲领先的 IP VPN 提供商。享受更高的可管理性和可扩展性,在多个站点之间交付 IP 流量或数据包,拥有亚太地区最大的 IP 骨干网。 1,保证正常运行时间,在网络链路发…...

【Unity动画系统】Unity动画系统Animation详解,参数细节你是否弄清?

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…...

K8S Helm安装RocketMQ standalone单机版,配置外网地址注册到nameserver中方便本地开发

K8S Helm安装RocketMQ standalone单机版,配置外网地址注册到nameserver中方便本地开发 helm地址 rocketmq 3.0.2 sir5kong/rocketmq helm repo add rocketmq https://helm-charts.itboon.top/rocketmq helm pull rocketmq/rocketmq tar -xvf rocketmq-3.0.2.t…...

分布式基础概念

分布式基础概念 1 微服务 微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化部署机制…...

蓝桥杯python比赛历届真题99道经典练习题 (89-99)

【程序89】 题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。 1.程序分析: 2.程序源代码: from sys import stdout if __n…...

蚂蚁矿机AntMiner T9+引出IO定义

这个板子只有s9的原理图参考,大部分一样但是也有很多改动。 下面是自己测出来的IO。全部为PL,没有PS引出。 共计56个引脚可用,但是不是都是完整的差分对,而且显然有些走线没办法高速跑。 测试方法 万用表先区分VCC GND和IO(对地…...

浅析 Dockerfile 构建缓存:原理与优化方法

Docker镜像的分层结构 Docker镜像是由一层一层的文件系统组成,UnionFS将这些镜像层堆叠在一起镜像层是只读的,构建完成后就不能更改了,即使在新的镜像层修改或删除了某些文件,也不会影响之前的镜像层内容用Dockerfile构建镜像时&…...

隐藏层节点数对分类准确率的影响

直线上有9个格子,4个石子, 数量 结构编号 6 0 1 1 1 1 0 0 0 0 0 5 2 1 1 1 0 1 0 0 0 0 5 1 1 0 1 1 1 0 0 0 0 4 3 1 1 0 0 1 1 0 0 0 4 4 1 0 1 0 1 1 0 0 0 3 5 1 0 1 0 1 0 1 0…...

【水浸传感器】软硬件一体水浸监测整套方案远程监测解决各种环境漏水问题

一、痛点分析 在工业生产中,水浸传感器可以安装在数据中心、半导体厂房、输油管道、车间仓库、变电室等易发生水浸的区域。一旦检测到漏水情况,立即发出信号反馈。然而,水浸传感器分散在各个地点,导致管理不集中、不便捷&#xf…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...