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

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

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

相关文章

[2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件

哈喽大家好!你有没有需要适用于电脑的免费数据恢复软件呢?数据丢失可是个烦心事,无论是硬件故障还是软件损坏,甚至是意外删除、格式化或计算机病毒,都让人郁闷至极。当你遇到数据丢失的情况时,你一定希望能…

【Git】Git的基本操作

前言 Git是当前最主流的版本管理器,它可以控制电脑上的所有格式的文件。 它对于开发人员,可以管理项目中的源代码文档。(可以记录不同提交的修改细节,并且任意跳转版本) 本篇博客基于最近对Git的学习,简单介…

Python中的用户交互函数详解,提升用户体验!

更多Python学习内容:ipengtao.com 用户进行交互的Python应用程序,有许多常用的用户交互函数可以帮助创建更具吸引力和友好的用户界面。本文将介绍一些常用的Python用户交互函数,并提供详细的示例代码,以帮助大家更好地理解它们的用…

右键添加 idea 打开功能

1.开始运行regedit 2.找到: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell _3.开始设置 一、右键shell目录新建项Idea二、右键Idea新建command三、选择Idea 右侧空白出新建字符串 名字为Icon 值填入idea的运行程序地址 四、选择command 默认项填入idea的运行程序地址…

技术探秘:在RISC Zero中验证FHE——RISC Zero应用的DevOps(2)

1. 引言 前序博客: 技术探秘:在RISC Zero中验证FHE——由隐藏到证明:FHE验证的ZK路径(1) 技术探秘:在RISC Zero中验证FHE——由隐藏到证明:FHE验证的ZK路径(1) 中&…

【privateGPT】使用privateGPT训练您自己的LLM

了解如何在不向提供商公开您的私人数据的情况下训练您自己的语言模型 使用OpenAI的ChatGPT等公共人工智能服务的主要担忧之一是将您的私人数据暴露给提供商的风险。对于商业用途,这仍然是考虑采用人工智能技术的公司最大的担忧。 很多时候,你想创建自己…

【GOLANG】使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置

直接 使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置 1、简单安装 Goanno 插件 File->Settings->Plugins , 搜索 Goanno Normal Method 配置内容如下: // Title ${function_name} // Description ${todo} // Author mumu ${date} ${time} // Par…

技能分析:这就是人们写在简历上的内容

您希望您的技能部分听起来像其他人一样吗?另一方面,您是否想遗漏一项顶级技能,因为许多其他简历也列出了它?在脱颖而出和涵盖雇主寻求的所有技能之间找到平衡可能是一个挑战。 优秀的简历技能部分会考虑到每个雇主所寻求的特质。…

海云安亮相2023北京国际金融安全论坛,助力金融企业数字化转型降本增效

近日,2023北京国际金融安全论坛暨金融科技标准认证生态大会在北京金融安全产业园成功举办。深圳海云安网络安全技术有限公司(以下简称“海云安”)受邀参展亮相此次大会。海云安作为国内领先的金融科技服务商,展示了开发安全系列产…

Unity坦克大战开发全流程——开始场景——排行榜数据逻辑

开始场景——排行榜数据逻辑 排行榜单条数据 排行榜列表 然后在数据管理类中声明一个对应的字段 初始化数据 然后再在上一节课所编写的UpdatePanelInfo函数中处理数据更新的逻辑 时间换算算法 然后再在数据管理类中编写一个在排行榜中添加数据的方法以提供给外部 直到当前RankI…

【BERT】深入理解BERT模型1——模型整体架构介绍

前言 BERT出自论文:《BERT:Pre-training of Deep Bidirectional Transformers for Language Understanding》 2019年 近年来,在自然语言处理领域,BERT模型受到了极为广泛的关注,很多模型中都用到了BERT-base或者是BE…

搜索算法和推荐算法、广告算法的区别

广告和推荐算法的技术框架比较相似,在线计算时都分为召回(candidates generating)和排序(candidates ranking)两个阶段(这似乎是计算资源有限条件下,所有检索问题的通用架构)。 在某…

RabbitMQ详解

RabbitMQ 概念 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。 AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息&a…

2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题)

2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题) 2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题) 第一部分:数据安全防护(30%) 第二部分:数据安全管理(30%) 第三部分:数据安全处置(40%) 项目介绍…

【JavaEE】多线程(7) -- 线程池的概念和简单实现

目录 1.线程池是什么 2.标准库中的线程池 2.1ThreadPoolExecutor 2.2构造方法参数介绍 2.3拒绝策略(面试易考) 2.4Executor的使用 3.实现线程池 1.线程池是什么 线程池是一种用来管理线程的机制,它可以有效地控制线程的创建、复用和销毁,从而提高程…

程序的编译、链接

目录 前言: 前置知识回顾 宏 宏定义常量 宏定义语句 宏定义函数 条件编译 应用场景 编译过程概览 预编译阶段 编译阶段 汇编阶段 链接阶段 前言: 在ANSI C的任何一种实现中,存在两种不同的环境,第1种是翻译环境&#x…

GPT-5、开源、更强的ChatGPT!OpenAI公布2024年计划

年终岁尾,正值圣诞节热闹气氛的OpenAI写下了2024年的发展清单。 OpenAI联合创始人兼首席执行官Sam Altman在社交平台公布,AGI(稍晚一些)、GPT-5、更好的语音模型、更高的费率限制; 更好的GPTs;更好的推理…

大数据- Hadoop入门

目录 🐶2.1 hadoop的简介 1. 概述 2. 什么是分布式? 3. Hadoop的指代 🐶2.2 hadoop的发展历程 🐶2.3 hadoop的版本介绍 🐶2.4 hadoop的常用端口号 🐶2.5 hadoop的设计目的 🐶2.6 hadoo…

Java集合/泛型篇----第二篇

系列文章目录 文章目录 系列文章目录前言一、说说List,Set,Map三者的区别二、Array与ArrayList有什么不一样?三、Map有什么特点四、集合类存放于 Java.util 包中, 主要有几 种接口前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。…

upload-labs Pass-03(黑名单验证,特殊后缀)问题纠正

php任何后缀名解析 背景:为了验证php解析不依靠后缀名,可以是任何后缀名,纠正upload-labs Pass-03(黑名单验证,特殊后缀)里所说的几个固定的后缀名理论是错误的。1 部署1.1 环境准备1.1.1 系统、内核&#…