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

设计模式之创建者模式

文章目录

  • 一、介绍
  • 二、应用
  • 三、案例
    • 1. 麦当劳1+1随心配
    • 2. 代码演示
    • 3. 演示结果
  • 四、优缺点
  • 五、送给读者

一、介绍

建造者模式(Builder Pattern)属于创建型设计模式,很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说,这句话难免有点晦涩难懂,何为复杂对象?何为创建过程,何为细节表示?

复杂对象:一个对象中的成员属性出了基本数据类型及其对应的封装类型,还包含有其他类型对象。例如:在对象A中包含对象B的引用,对象B中又包含对象C的引用。

创建过程:一个对象的实例化和初始化过程。如new一个对象后再调用其set方法为其初始化。

细节表示:在对一个对象初始化时,通过set方法表示其创建的细节。说白了,细节表示就是该对象的成员变量。

在一般情况下,我们要创建一个完整的对象时,往往是通过两个步骤完成:①实例化(即new一个对象);②初始化(即调用set方法对其属性赋值)。这是一种创建过程与细节表示耦合的情况。即:一个对象的实例化和初始化过程就表示为其创建过程;而在初始化过程中通过set方法我们又了解到了其内部属性(即细节表示)

而在建造者模式中,我们只需要通过一个对象的建造者(Builder)所提供的方法向其描述对象的细节,该然后该建造者通过其核心方法build()将对象实例化并补充其细节。这就是建造者的核心思想。

二、应用

  • java中的StringBuilder类。我们通过其提供的各种重载的append()方法,描述一个字符串的细节,最后通过toString()方法获得String实例。
  • OkHttp中应用了大量的建造者模式。如创建请求客户端时,使用OkHttpClient的内部类Builder来描述请求的细节,然后通过build()方法获得一个OkHttpClient实例。

三、案例

1. 麦当劳1+1随心配

我们以麦当劳随心配1+1套餐为例,当用户选择该套餐时,该套餐规定选择一个任意主食 + 一个任意冷饮。如下图所示

  • 选择主食

    在这里插入图片描述

  • 选择冷饮

    在这里插入图片描述

添加到购物车后,我们可以看到该套餐详情

在这里插入图片描述

2. 代码演示

  • 新建套餐抽象接口Meal,以及实现该接口的随心配1+1套餐SuiXinPeiMeal

    public interface Meal {// 套餐价格Float getCost();// 套餐详情void order();
    }public class SuiXinPeiMeal implements Meal{// 主食private Food food;// 冷饮private ColdDrink coldDrink;// 省略get、set方法...// 套餐价格@Overridepublic Float getCost() {return 5F;}// 套餐详情@Overridepublic void order() {System.out.println("随心配1+1套餐:");System.out.println("主食:" + food.getName() + ",单价:" + food.getCost());System.out.println("冷饮:" + coldDrink.getName() + ",单价:" + coldDrink.getCost());System.out.println("套餐价格:" + getCost());}
    }
    
  • 新建一个随心配1+1套餐的创建者SuiXinPeiMealBuilder

    public class SuiXinPeiMealBuilder {private Food food;private ColdDrink coldDrink;// 向套餐中添加主食public void addFood(Food food) {this.food = food;}// 向套餐中添加冷饮public void addColdDrink(ColdDrink coldDrink) {this.coldDrink = coldDrink;}// 创建套餐public Meal build() {if (food == null) {throw new RuntimeException("请选择一个主食");}if (coldDrink == null) {throw new RuntimeException("请选择一个冷饮");}SuiXinPeiMeal meal = new SuiXinPeiMeal();meal.setFood(food);meal.setColdDrink(coldDrink);return meal;}
    }
    
  • 新建单品抽象接口SingleProduct

    public interface SingleProduct {// 单品名称String getName();// 单品价格Float getCost();
    }
    
  • 新建主食抽象接口Food、及其实现类Chicken鸡块、Fries薯条、Hamburger汉堡

    public interface Food extends SingleProduct {
    }public class Chicken implements Food{@Overridepublic String getName() {return "鸡块";}@Overridepublic Float getCost() {return 13F;}
    }public class Fries implements Food{@Overridepublic String getName() {return "薯条";}@Overridepublic Float getCost() {return 10F;}
    }public class Hamburger implements Food {@Overridepublic String getName() {return "汉堡";}@Overridepublic Float getCost() {return 15F;}
    }
    
  • 新建冷饮抽象接口ColdDrink、及其实现类CocaCola可乐、NoSugarCola无糖可乐、Sprite雪碧

    public interface ColdDrink extends SingleProduct {
    }public class CocaCola implements ColdDrink{@Overridepublic String getName() {return "可乐";}@Overridepublic Float getCost() {return 3.8F;}
    }public class NoSugarCola implements ColdDrink {@Overridepublic String getName() {return "无糖可乐";}@Overridepublic Float getCost() {return 5.0F;}
    }public class Sprite implements ColdDrink {@Overridepublic String getName() {return "雪碧";}@Overridepublic Float getCost() {return 8F;}
    }
    
  • main()方法中进行套餐模拟

    public static void main(String[] args) {// 套餐:鸡块+可乐SuiXinPeiMealBuilder builder1 = new SuiXinPeiMealBuilder();// 选择鸡块builder1.addFood(new Chicken());// 选择可口可乐builder1.addColdDrink(new CocaCola());// 创建订单Meal meal1 = builder1.build();// 输出订单详情meal1.order();System.out.println("==============================================");// 套餐:汉堡+雪碧SuiXinPeiMealBuilder builder2 = new SuiXinPeiMealBuilder();builder2.addFood(new Hamburger());builder2.addColdDrink(new Sprite());Meal meal2 = builder2.build();meal2.order();
    }
    

3. 演示结果

运行上述代码,结果如下

在这里插入图片描述

四、优缺点

  • 优点
    • 对象的创建过程与其细节表示分离,即解耦。
  • 缺点:
    • 产生多余的建造者Builder类,且每当添加一种套餐,就需要多写一个对应的套餐建造者类。
    • 建造者与对象之间耦合,当修改对象结构时,建造者也要修改。
    • 可读性相对较差。

五、送给读者

  • 在非必要的情况下,业务代码中不建议使用该设计模式,没有性能上的优化却导致可读性变差,属于炫技型设计模式。
  • 如果本文对你有所帮助,别忘了安排博主一顿麦当劳随心配1+1套餐哦。


纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

相关文章:

设计模式之创建者模式

文章目录 一、介绍二、应用三、案例1. 麦当劳11随心配2. 代码演示3. 演示结果 四、优缺点五、送给读者 一、介绍 建造者模式(Builder Pattern)属于创建型设计模式,很多博客文章的对它的作用解释为用于将复杂对象的创建过程与其细节表示分离。但对于初学者来说&…...

Java之包,权限修饰符,final关键字详解

包 2.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术,不同的技术类放在不同的包下,方便管理和维护。 在IDEA项目中,建包的操作如下: 包名的命名规范: 路径名.路径名.xxx.xxx // 例如&#xff…...

“深入解析JVM:Java虚拟机内部原理揭秘“

标题:深入解析JVM:Java虚拟机内部原理揭秘 摘要:本文将深入探讨Java虚拟机(JVM)的内部原理,包括JVM的架构、运行时数据区域、垃圾回收机制以及即时编译器等重要组成部分。通过对JVM内部原理的解析&#xf…...

Mac下Jmeter安装及基本使用

本篇文章只是简单的介绍下Jmeter的下载安装和最基本使用 1、初识Jmeter 前一段时间客户端app自测的过程中,有偶现请求某个接口返回数据为空的问题,领导让我循环100次请求这个接口,看看有没有结果为空的问题。听同事说有Jmeter的专业测试工具…...

云计算与边缘计算:加速数字化转型的关键驱动力

云计算和边缘计算技术正以惊人的速度改变着企业的业务和基础架构。这些先进的技术为企业带来了灵活性、可扩展性和成本效益的优势,重新定义了业务运作的方式。 云计算是通过互联网将计算资源提供给用户的一种服务模式。通过云计算,企业可以将应用程序、…...

TheGem主题 - 创意多用途和高性能WooCommerce WordPress主题/网站

TheGem主题概述 – 适合所有人的TheGem 作为设计元素、样式和功能的终极 Web 构建工具箱而设计和开发,TheGem主题将帮助您在几分钟内构建一个令人印象深刻的高性能网站,而无需触及一行代码。不要在编码上浪费时间,探索你的创造力&#xff01…...

Pytorch-day10-模型部署推理-checkpoint

模型部署&推理 模型部署模型推理 我们会将PyTorch训练好的模型转换为ONNX 格式,然后使用ONNX Runtime运行它进行推理 1、ONNX ONNX( Open Neural Network Exchange) 是 Facebook (现Meta) 和微软在2017年共同发布的,用于标准描述计算图的一种格式…...

vue使用websocket

建立websocket.js // 信息提示 import { Message } from element-ui // 引入用户id import { getTenantId, getAccessToken } from /utils/auth// websocket地址 var url ws://192.168.2.20:48081/websocket/message // websocket实例 var ws // 重连定时器实例 var tt // w…...

jmeter入门:接口压力测试全解析

一.对接口压力测试 1.配置 1.添加线程组(参数上文有解释 这里不介绍) 2.添加取样器 不用解释一看就知道填什么。。。 3.添加头信息(否则请求头对不上) 也不用解释。。。 4.配置监听器 可以尝试使用这几个监听器。 2.聚合结果…...

go、java、.net、C#、nodejs、vue、react、python程序问题进群咨询

1、面试辅导 2、程序辅导 3、一对一腾讯会议辅导 3、业务逻辑辅导 4、各种bug帮你解决。 5、培训小白 6、顺利拿到offer...

树莓派4B最新系统Bullseye 64 bit使用xrdp远程桌面黑屏卡顿问题

1、树莓派换源 打开源文件 sudo nano /etc/apt/sources.list注释原来的,更换为清华源 deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye main contrib non-free deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bullseye-updates main contrib no…...

EasyExcel入门介绍及工具类,网络下载excel

前言:在这里分享自己第一次使用EasyExcel并且编写工具类,且在接口中支持excel文件下载的一系列流程,包含所有前后端(JSJAVA)完整代码,可以根据自己需要自行提取,仅供参考。 一.引入EasyExcel依赖…...

【HarmonyOS北向开发】-04 ArkTS开发语言-ArkTS基础知识

飞书原文档:Docs...

【Alibaba中间件技术系列】「RocketMQ技术专题」小白专区之领略一下RocketMQ基础之最!

应一些小伙伴们的私信,希望可以介绍一下RocketMQ的基础,那么我们现在就从0开始,进入RocketMQ的基础学习及概念介绍,为学习和使用RocketMQ打好基础! RocketMQ是一款快速地、可靠地、分布式、容易使用的消息中间件&#…...

营销活动:提升小程序的用户活跃度的关键

在现今竞争激烈的商业环境中,小程序已成为企业私域营销的重要工具之一。然而,拥有一个小程序并不足以保证用户的活跃度。营销活动作为推动用户参与的有效方式,对于提升小程序的用户活跃度起着至关重要的作用。本文将深入探讨营销活动在提升小…...

Neo4j之CALL基础

CALL 语句用于调用 Neo4j 数据库中预定义的函数、过程或者自定义的函数。它是用来执行一些特定操作或计算的重要工具。以下是一些常用的 CALL 语句示例和解释: 调用内置函数: CALL db.labels()这个示例中,调用了内置函数 db.labels() 来获取…...

【TypeScript】元组

元组(Tuple)是 TypeScript 中的一种特殊数据类型,它允许你定义一个固定数量和类型的元素组合。元组可以包含不同类型的数据,每个数据的类型在元组中都是固定的。以下是 TypeScript 中元组的基本用法和特点: // 声明一…...

数据仓库一分钟

数据分层 一、数据运营层:ODS(Operational Data Store) “面向主题的”数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL…...

提升Python代理程序性能的终极解决方案:缓存、连接池和并发

在开发Python代理程序时,优化性能是至关重要的。本文将为你介绍一套终极解决方案,通过缓存、连接池和并发处理等技术,极大地提升Python代理程序的效率和稳定性。 游戏国内地更换虚拟含ip地址数据库地区 1.缓存技术 缓存是 .0-*-696ES2 0一…...

CSS和AJAX阶段学习记录

1、AJAX的工作原理: 如图所示,工作原理可以分为以下几步: 网页中发生一个事件(页面加载、按钮点击) 由 JavaScript 创建 XMLHttpRequest 对象 XMLHttpRequest 对象向 web 服务器发送请求 服务器处理该请求 服务器将响应…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) ​遍历字符串​:通过外层循环逐一检查每个字符。​遇到 ? 时处理​: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: ​与…...

云原生安全实战:API网关Kong的鉴权与限流详解

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块&#xff0…...