趣解建造者模式之网红小王购车记

news2024/12/23 20:01:16

一、前言

本文章是关于设计模式中的建造者模式的,也称构建者模式/生成器模式,英文我们称之为Builder Pattern。在开展讲解之前,我们先把该模式的定义了解一下。

建造者模式的定义:

该模式可以实现产品的封装构造过程,并允许按步骤构造产品。

该模式的优点:

可以将一个复杂对象的创建过程封装起来,允许对象通过多个步骤来创建,并且可以改变过程;它也可以向客户隐藏产品内部的表现;因为客户只看到一个抽象接口,所以产品的具体实现是可以被替换的。

用途:

经常被用来创建组合结构。

缺点:

与工厂模式相比,采用生成器模式创建对象的客户,需要具备更多的领域知识。

二、讲个小故事

小王家境一般,但是呢,通过自己的努力成为了一个小网红,收入也逐渐多了起来。他从小就羡慕开汽车的人,所以,自己也决定买辆车。

他首先去了奥迪的4s店,车子很多,也很不错。4S店的销售人员给他介绍了很多车型,他看中了奥迪的A4L,各方面都挺喜欢的,然后就打算付款了。

正在这个时候,他的助理给他打电话,“小王!榜一大哥准备签约你了!签约费用给你1000万!你发达了!”,小王一听,高兴坏了,这不一下子鸡窝变凤凰了嘛!他挂断电话,觉得自己得买一辆更独特的汽车,而不是大街上较为常见的A4L了,然后他问销售人员,这个车我能自己定制不?销售人员说,我们只有一些选配项,定制不了。小王很失望,他太想拥有一辆“专属”自己的车子了。

这个时候,销售人员建议他,去看一看保时捷,定制的项目非常多。然后呢,他就去了保时捷4s店,从那边他发现,从小的轮毂logo,再到外观中控,都能选配和定制,这就太好了,他选了好多自己喜欢的定制型,这样,一辆完完全全“专属”小王的保时捷跑车就定制好了。

三、模式的使用方式

从上面的例子我们可以看到,对于普通汽车来说,大多采用固定的一些配置项,我们获得的汽车往往没有特殊化定制的需求,那么这种情况,我们通过工厂方法或者抽象工厂就可以满足需求。

但是对于高端客户,往往需要定制化的东西比较多,那么创建出来的实例对象也更为复杂和灵活,对于这种场景,我们就可以通过Builder模式来进行对象的创建了。

所以,当我们需要自定义各种对象的细节部分,然后最终拼装出一个个性化实例对象时,就非常适合采用建造者模式。

获得一个车架子,拼装车门,拼装轮胎,拼装发动机,拼装变速箱……,然后获得最终的个性化汽车。

3.1> 类图

在通过上面的例子了解了建造者模式之后,我们就通过类图的方式,展示一下该模式。在下图中,我们提供了两种场景:分别是客户不可定制客户可以定制,具体选择哪种实现方式,可以根据具体的业务场景来自行选择:

3.2> 代码实现

创建一个汽车实体类Car,里面包含4个组件,分别是:汽车引擎(engine)、变速齿轮(gear)、车门(door)和汽车轮胎(wheel),代码如下所示:

@ToString
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {
    private String engine = "普通标准的发动机";
    private String gear = "普通标准的齿轮";
    private String door = "普通标准的车门";
    private String wheel = "普通标准的轮胎";
}

创建构造器接口Builder,提供安装引擎(initalEngine)、安装齿轮(initalGear)、安装车门(initalDoor)、安装轮胎(initailWheel)等功能:

public interface Builder {
    // 安装引擎
    Builder initalEngine(String engine);

    // 安装齿轮
    Builder initalGear(String gear);

    // 安装车门
    Builder initalDoor(String door);

    // 安装轮胎
    Builder initailWheel(String wheel);

    // 获得构建后的汽车
    Car getCar();
}

根据Builder接口,实现创建奥迪车的Builder实现类——AudiBuilder:

public class AudiBuilder implements Builder {
    private Car car;

    public AudiBuilder() {
        car = new Car("Audi普通的发动机",
                "Audi普通标准的齿轮",
                "Audi普通标准的车门",
                "Audi普通标准的轮胎");
    }

    @Override
    public Builder initalEngine(String engine) {
        car.setEngine(engine);
        return this;
    }

    @Override
    public Builder initalGear(String gear) {
        car.setGear(gear);
        return this;
    }

    @Override
    public Builder initalDoor(String door) {
        car.setDoor(door);
        return this;
    }

    @Override
    public Builder initailWheel(String wheel) {
        car.setWheel(wheel);
        return this;
    }

    @Override
    public Car getCar() {
        return car;
    }
}

根据Builder接口,实现创建宝马车的Builder实现类——BMWBuilder:

public class BMWBuilder implements Builder {
    private static Car car = new Car("BMW普通的发动机", 
                                     "BMW普通标准的齿轮", 
                                     "BMW普通标准的车门",
                                     "BMW普通标准的轮胎");

    @Override
    public Builder initalEngine(String engine) {
        car.setEngine(engine);
        return this;
    }

    @Override
    public Builder initalGear(String gear) {
        car.setGear(gear);
        return this;
    }

    @Override
    public Builder initalDoor(String door) {
        car.setDoor(door);
        return this;
    }

    @Override
    public Builder initailWheel(String wheel) {
        car.setWheel(wheel);
        return this;
    }

    @Override
    public Car getCar() {
        return car;
    }
}

创建工人类Worker,这个工人可以创建奥迪A4L型号汽车(createA4LCar)和奥迪R8跑车(createR8Car),也可以创建普通的宝马汽车(createCommonBMW):

public class Worker {
    Car createA4LCar() {
        return new AudiBuilder().
        initalEngine("Audi的4缸发动机").
        initalGear("6速双离合变速箱").getCar();
    }
    Car createR8Car() {
        return new AudiBuilder().
        initalEngine("16缸跑车引擎").
        initalDoor("碳纤维轻量级车门").
        initalGear("7档湿式双离合变速箱").
        initailWheel("米其林Top2竞速级轮胎").getCar();
    }
    Car createCommonBMW() {
        return new BMWBuilder().getCar();
    }
}

创建测试类BuilderTest,使得工人创建奥迪A4L、奥迪R8跑车和普通的宝马汽车:

public class BuilderTest {
    public static void main(String[] args) {
        Worker worker = new Worker();
        Car audiR8 = worker.createR8Car();
        Car audiA4L = worker.createA4LCar();
        Car commonBMW = worker.createCommonBMW();

        System.out.println("audiR8=" + audiR8);
        System.out.println("audiA4L=" + audiA4L);
        System.out.println("commonBMW=" + commonBMW);
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

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

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

相关文章

《2023 中国人工智能人才学习白皮书》完整下载!

Datawhale发布 2023 中国人工智能人才学习白皮书 I 导读 日前,由 Datawhale 联合上海白玉兰开源开放研究院、和鲸科技、江南大学教育信息化研究中心编写的《2023中国人工智能人才学习白皮书》(下简称“白皮书”)于8月24日正式发布。 学界大咖…

数字化转型的关键点是什么?

数字化转型的关键点是指企业或组织在适应并利用数字技术的过程中需要关注和把握的关键要素。以下是数字化转型的关键点: 领导力和战略:数字化转型需要高层领导层的支持和积极参与。领导层需要制定明确的数字化战略,并将其与企业的整体战略相结…

AI大模型的使用-语义检索,利用Embedding优化你的搜索功能

Embedding 向量适合作为一个中间结果,用于传统的机器学习场景,比如分类、聚类。 Completion 接口,一方面可以直接拿来作为一个聊天机器人,另一方面,你只要善用提示词,就能完成合理的文案撰写、文本摘要、机…

深度解析 PostgreSQL Protocol v3.0(一)

引言 PostgreSQL 使用基于消息的协议在前端(也可以称为客户端)和后端(也可以称为服务器)之间进行通信。该协议通过 TCP/IP 和 Unix 域套接字支持。 《深度解析 PostgreSQL Protocol v3.0》系列技术贴,将带大家深度了…

docker部署nginx,部署springboot项目,并实现访问

一、先部署springboot项目 1、安装docker: yum install docker -y 2、启动docker: service docker start 重启: service docker restart 3、查看版本: docker -v 4、使设置docker.service生效(路径:…

【数据分析,附源码】MATLAB R2022b安装教程

软件下载 软件:MATLAB版本:2022b语言:简体中文大小:19.37G安装环境:Win11/Win10硬件要求:CPU2.6GHz 内存8G(或更高)下载通道①百度网盘丨64位下载链接:https://pan.baidu.com/s/1R1…

ssm高校教师科研信息展示网站源码和论文

ssm高校教师科研信息展示网站源码和论文095 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面…

Mybatis1.9 批量删除

1.9 批量删除 1.9.1 编写接口方法1.9.2 编写SQL语句1.9.3 编写测试方法 如上图所示,用户可以选择多条数据,然后点击上面的 删除 按钮,就会删除数据库中对应的多行数据。 1.9.1 编写接口方法 在 BrandMapper 接口中定义删除多行数据的方法。…

Mysql高阶语句 (一)

一、常用查询 (增、删、改、查) 对 MySQL 数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理。 例如只取 10 条数据、对查询结果进行排序或分组等等 1、按关键字排序 PS:类比于windows 任务管理器 使用 SELECT 语句…

成都瀚网科技有限公司:抖店精选联盟企业是什么?

我很高兴为您提供有关如何加入抖店特色联盟企业以及加入的好处的信息。在这篇文章中,我将为大家详细介绍如何申请加入抖店精选的关联公司,并讲解加入的好处。希望能够帮助您更好地了解和使用抖店精选联盟企业平台。 1、如何加入抖店精选联盟企业&#xf…

亚马逊鲲鹏系统是怎么操作测评的

亚马逊鲲鹏系统可以注册亚马逊买家号、养号、下单留评等,是一款功能比较齐全的测评软件,具体操作如下: 首先我们需要先准备好买家账号,账号可以直接去购买已经注册好了的账号,也可以准备好账号所需要的一些邮箱、ip、…

做邮件营销前,这些注意事项一定要知晓

邮件营销是一种有效的网络营销手段,可以帮助企业与潜在客户建立长期联系,促进销售和品牌认知。相比于其他的营销手段,邮件营销针对性更强,可以根据不同类型用户所具有的特征和属性进行营销。其次,邮件营销的覆盖范围较…

EPICS asyn连接测试例程

1) 用makeBaseApp.pl新建一个EPICS IOC的目录结构: rootorangepi5:/usr/local/EPICS/program/testConnect# ls configure iocBoot Makefile testConnectApp2) 编辑configure目录下的RELEASE文件,定义asyn模块所在的路径: ... SUPPORT/us…

Java“牵手”1688拍立淘接口数据,图片搜索1688商品,图片识别商品接口,1688API申请指南

1688商城是一个网上购物平台,售卖各类商品,包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取1688商品列表和商品详情页面数据,您可以通过开放平台的接口或者直接访问1688商城的网页来获取商品详情信息。以下是两种常用方法的介绍&…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,动态数组(重点推荐))七(129)

需求:前端根据后端的返回数据:画统计图; 说明: 1.X轴为地域,Y轴为地域出现的次数; 2. 动态展示(有地域展示,没有不展示,且高低排序) Demo案例: …

使用卷积操作实现因子分解机

本文将介绍如何使用卷积操作实现因子分解机器。卷积网络因其局部性和权值共享的归纳偏差而在计算机视觉领域获得了广泛的成功和应用。卷积网络可以用来捕获形状的堆叠分类特征(B, num_cat, embedding_size)和形状的堆叠特征(B, num_features, embedding_size)之间的特征交互。 …

【C++】C++11的新特性(上)

引入 C11作为C标准的一个重要版本,引入了许多令人振奋的新特性,极大地丰富了这门编程语言的功能和表达能力。本章将为您介绍C11的一些主要变化和改进,为接下来的章节铺垫。 文章目录 引入 一、列表初始化 1、1 {} 初始化 1、2 std::initiali…

问道管理:macd参数改良设置?

MACD目标是一种广泛应用的技能剖析目标,其特色在于能够同时反映趋势和动量改变。可是,很多买卖者感到困惑的是,怎么设置MACD的参数才能更好地指导买卖。 1. MACD目标参数解析 MACD目标是依据两个移动平均线的穿插来判别商场的趋势与动量改变…

解压jar包并导入库环境

背景 因为各种历史原因,当初的maven依赖环境已下载不了了,所以需要从生产环境的jar包里,获取库环境来本地运行。 但是网上很多方法都是用mvn install命令,一个个jar包导入的,不符合我的需求(需要导入280多…

Linux 虚拟机同步时间crontab以及crond详解

目录 一 Linux 虚拟机同步时间设置 1. 检查是否安装cron服务(即时间同步器) 2. 下载时间同步器 3. 编辑crontab 内容 4. 同步更新电脑网络时间 5.设置 reload 6. 查看 crond 状态 二 crond 详解 1. 启动/关闭cron服务 2. crontab命令格式 3. …