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

设计模式之建造者模式(通俗易懂--代码辅助理解【Java版】)

文章目录

  • 设计模式概述
  • 1、建造者模式
  • 2、建造者模式使用场景
  • 3、优点
  • 4、缺点
  • 5、主要角色
  • 6、代码示例:
    • 1)实现要求
    • 2)UML图
    • 3)实现步骤:
      • 1)创建一个表示食物条目和食物包装的接口
      • 2)创建实现Packing接口的实体类
      • 3)创建实现 Item 接口的抽象类,该类提供了默认的功能
      • 4)创建扩展了 Burger 和 ColdDrink 的实体类
      • 5)创建一个Meal类,带有上面定义的Item对象
      • 6)创建一个MealBuilder类,实际的builder类负责创建Meal对象
      • 7)BuilderPatternDemo使用MealBuilder来演示建造者模式(Builder Pattern)
      • 8)执行程序,输出结果:
  • 7、总结

设计模式概述

创建型模式:工厂方法、抽象方法、建造者、原型、单例。
结构型模式有:适配器、桥接、组合、装饰器、外观、享元、代理。
行为型模式有:责任链、命令、解释器、迭代器、中介、备忘录、观察者、状态、策略、模板方法、访问者。
常用设计模式:
单例模式、工厂模式、代理模式、策略模式&模板模式、门面模式、责任链模式、装饰器模式、组合模式、builder模式。

1、建造者模式

  • 建造者模式是一种创建型设计模式,它允许你创建复杂对象的步骤与表示方式相分离,从而可以创建具有不同表示形式的对象。
  • 旨在通过逐步构造复杂对象的各个部分来简化对象的创建
  • 它与工厂模式的不同之处在于,建造者模式更注重将一个复杂对象的构造过程进行拆解,并且可以根据需求一步步定制地构建

2、建造者模式使用场景

  • 构造函数包含多个参数或嵌套对象且顺序不固定的对象创建:例如,像 Pizza 这样可以自定义不同配料的场景,建造者模式可以让我们有选择性地添加不同的部分,而不需要冗长的构造函数。
  • 需要可读性强的对象创建代码:对于那些复杂对象,建造者模式可以让代码更加清晰。
  • 对象的不可变性(Immutable Object):通过建造者模式,我们可以有效创建不可变对象(对象一旦创建就不可更改),这有助于避免线程安全问题。

3、优点

  • 灵活性高:可以根据不同需求构建不同的对象版本。
  • 代码清晰:由于建造者模式将对象的创建与表示分开,构建过程变得更加可读和维护。
  • 避免了构造函数过载:当构造函数包含过多参数时,使用建造者模式可以避免参数爆炸问题。

4、缺点

  • 可能增加代码复杂度:在某些场景下,如果对象并不复杂,使用建造者模式可能导致不必要的代码冗余。
  • 需要额外的Builder类:每个复杂对象都需要有一个对应的Builder类,可能会增加代码量。

5、主要角色

建造者模式包含以下几个主要角色:

  • 产品(Product):要构建的复杂对象。产品类通常包含多个部分或属性。
  • 抽象建造者(Builder):定义了构建产品的抽象接口,包括构建产品的各个部分的方法。
  • 具体建造者(Concrete Builder):实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
  • 指导者(Director):负责调用建造者的方法来构建产品,指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。

6、代码示例:

1)实现要求

  • 我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

  • 我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

  • 然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal。

2)UML图

在这里插入图片描述

3)实现步骤:

1)创建一个表示食物条目和食物包装的接口


// Item.java
public interface Item {public String name();public Packing packing();public float price();    
}//  Packing.java
public interface Packing {public String pack();
}

2)创建实现Packing接口的实体类

//  袋装   Wrapper.java
public class Wrapper implements Packing {@Overridepublic String pack() {return "Wrapper";}
}// 瓶装  Bottle.java
public class Bottle implements Packing {@Overridepublic String pack() {return "Bottle";}
}

3)创建实现 Item 接口的抽象类,该类提供了默认的功能

public abstract class Burger implements Item {@Overridepublic Packing packing() {return new Wrapper();}@Overridepublic abstract float price();
}
public abstract class ColdDrink implements Item {@Overridepublic Packing packing() {return new Bottle();}@Overridepublic abstract float price();
}

4)创建扩展了 Burger 和 ColdDrink 的实体类

public class VegBurger extends Burger {@Overridepublic float price() {return 25.0f;}@Overridepublic String name() {return "Veg Burger";}
}
public class ChickenBurger extends Burger {@Overridepublic float price() {return 50.5f;}@Overridepublic String name() {return "Chicken Burger";}
}
// Coke 类继承 ColdDrink
public class Coke extends ColdDrink {@Overridepublic float price() {return 30.0f;}@Overridepublic String name() {return "Coke";}
}

// Pepsi 类继承 ColdDrink
public class Pepsi extends ColdDrink {@Overridepublic float price() {return 35.0f;}@Overridepublic String name() {return "Pepsi";}
}

5)创建一个Meal类,带有上面定义的Item对象

import java.util.ArrayList;
import java.util.List;public class Meal {private List<Item> items = new ArrayList<Item>();    public void addItem(Item item){items.add(item);}public float getCost(){float cost = 0.0f;for (Item item : items) {cost += item.price();}        return cost;}public void showItems(){for (Item item : items) {System.out.print("Item : "+item.name());System.out.print(", Packing : "+item.packing().pack());System.out.println(", Price : "+item.price());}        }    
}

6)创建一个MealBuilder类,实际的builder类负责创建Meal对象

public class MealBuilder {public Meal prepareVegMeal (){Meal meal = new Meal();meal.addItem(new VegBurger());meal.addItem(new Coke());return meal;}   public Meal prepareNonVegMeal (){Meal meal = new Meal();meal.addItem(new ChickenBurger());meal.addItem(new Pepsi());return meal;}
}

7)BuilderPatternDemo使用MealBuilder来演示建造者模式(Builder Pattern)

public class BuilderPatternDemo {public static void main(String[] args) {MealBuilder mealBuilder = new MealBuilder();Meal vegMeal = mealBuilder.prepareVegMeal();System.out.println("Veg Meal");vegMeal.showItems();System.out.println("Total Cost: " +vegMeal.getCost());Meal nonVegMeal = mealBuilder.prepareNonVegMeal();System.out.println("\n\nNon-Veg Meal");nonVegMeal.showItems();System.out.println("Total Cost: " +nonVegMeal.getCost());}
}

8)执行程序,输出结果:

Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5

7、总结

建造者模式提供了一种优雅的方式来创建复杂的对象,特别适合在需要精细控制对象构建过程的场景下使用。通过分离构建过程和对象本身,它可以使代码更加简洁、可读,且易于维护。尽管它有时会增加代码的复杂度,但在应对复杂对象创建时,这种模式非常值得推荐

相关文章:

设计模式之建造者模式(通俗易懂--代码辅助理解【Java版】)

文章目录 设计模式概述1、建造者模式2、建造者模式使用场景3、优点4、缺点5、主要角色6、代码示例&#xff1a;1&#xff09;实现要求2&#xff09;UML图3)实现步骤&#xff1a;1&#xff09;创建一个表示食物条目和食物包装的接口2&#xff09;创建实现Packing接口的实体类3&a…...

文生视频算法

文生视频 Sora解决问题&#xff1a;解决思路&#xff1a; CogVideoX解决问题&#xff1a;解决思路&#xff1a; Stable Video Diffusion&#xff08;SVD&#xff09;解决问题&#xff1a;解决思路&#xff1a; 主流AI视频技术框架&#xff1a; Sora Sora: A Review on Backg…...

LoRA: Low-Rank Adaptation Abstract

LoRA: Low-Rank Adaptation Abstract LoRA 论文的摘要介绍了一种用于减少大规模预训练模型微调过程中可训练参数数量和内存需求的方法&#xff0c;例如拥有1750亿参数的GPT-3。LoRA 通过冻结模型权重并引入可训练的低秩分解矩阵&#xff0c;减少了10,000倍的可训练参数&#xf…...

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发&#xff08;21个&#xff09;二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发&#xff08;21个&#xff09; 二、嵌入式Linux驱动例程 三、…...

Unreal Engine——AI生成高精度的虚拟人物和环境(虚拟世界构建、电影场景生成)(一)

一、Unreal Engine 介绍 Unreal Engine&#xff08;虚幻引擎&#xff09;是由Epic Games开发的强大3D游戏开发引擎&#xff0c;自1998年首次发布以来&#xff0c;已经历了多个版本的迭代。虚幻引擎主要用于制作高品质的3D游戏&#xff0c;但也广泛用于电影、建筑、仿真等其他领…...

Emlog程序屏蔽用户IP拉黑名单插件

插件介绍 在很多时候我们需要得到用户的真实IP地址&#xff0c;例如&#xff0c;日志记录&#xff0c;地理定位&#xff0c;将用户信息&#xff0c;网站数据分析等,其实获取IP地址很简单&#xff0c;感兴趣的可以参考一下。 今天给大家带来舍力写的emlog插件&#xff1a;屏蔽…...

发送成绩的app或小程序推荐

老师们&#xff0c;新学期的第一次月考马上开始&#xff0c;是不是还在为如何高效、便捷地发布成绩而头疼呢&#xff1f;别担心&#xff0c;都2024年了&#xff0c;我们有更智能的方式来解决这个问题&#xff01; 给大家安利一个超级实用的工具——易查分小程序。这个小程序简…...

51单片机-AT24C02(IIC总线介绍及其时序编写步骤)-第一节(下一节实战)

IIC开始通信&#xff08;6大步&#xff09; 我以前的文章也有对基本常用的通信协议讲解&#xff0c;如SPI UART IIC RS232 RS485 CAN的讲解&#xff0c;可前往主页查询&#xff0c;&#xff08;2024.9.12,晚上20&#xff1a;53&#xff0c;将AT24C02存储芯片&#xff0c;掉电不…...

<<编码>> 第 11 章 逻辑门电路--或非门, 与非门, 缓冲器 示例电路

继电器或非门 info::操作说明 鼠标单击开关切换开合状态 闭合任意一个开关可使电路断开 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/code-hlchs-examples/assets/circuit/code-hlchs-ch11-19-nor-gate-by-relay.txt 或非门 i…...

股票api接口程序化报备,程序化交易监管对个人量化交易者有何影响

炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…...

如何自己搭建一个网站?

今天的文章总结适合0基础&#xff0c;网站搭建的技巧和流程&#xff0c;哪怕你是小白&#xff0c;不会编程&#xff0c;也可以制作非常漂亮且实用的企业网站&#xff0c;如果想做个人博客更是不在话下。希望我的经验能帮助更多没有过多的经费、没有建站基础的朋友。用户跟着我的…...

虚拟化数据恢复—断电导致虚拟机目录项被破坏的数据恢复案例

虚拟化数据恢复环境&#xff1a; 某品牌服务器&#xff08;部署VMware EXSI虚拟机&#xff09;同品牌存储&#xff08;存放虚拟机文件&#xff09;。 虚拟化故障&#xff1a; 意外断电导致服务器上某台虚拟机无法正常启动。查看虚拟机配置文件发现这台故障虚拟机除了磁盘文件以…...

[机器学习]聚类算法

1 聚类算法简介 # 导包 from sklearn.datasets import make_blobs import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.metrics import calinski_harabasz_score # 构建数据 x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1…...

JVM面试真题总结(七)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 解释GC的引用计数算法及其局限性 引用计数算法是一种非常直观、简…...

深入理解CASAtomic原子操作类详解

1.CAS介绍 什么是 CAS CAS&#xff08;Compare And Swap&#xff0c;比较与交换&#xff09;&#xff0c;是非阻塞同步的实现原理&#xff0c;它是CPU硬件层面的一种指令&#xff0c;从CPU层面能保证"比较与交换"两个操作的原子性。CAS指令操作包括三个参数&#x…...

C51单片机-单按键输入识别,键盘消抖

【实验目的】 独立按键的识别方法、键盘消抖等。 【实验现象】 每按一次独立键盘的S2键&#xff0c;与P1口相连的八个发光二极管中点亮的一个往下移动一位。 【实验说明】 关于按键去抖动的解释&#xff0c;我们在手动按键的时候&#xff0c;由于机械抖动或是其它一些非人为的因…...

基于CNN卷积神经网络迁移学习的图像识别实现

基于CNN卷积神经网络迁移学习的图像识别实现 基于CNN卷积神经网络迁移学习的图像识别实现写在前面一&#xff0c;原理介绍迁移学习的基本方法1.样本迁移&#xff08;Instance based TL&#xff09;2.特征迁移&#xff08;Feature based TL&#xff09;3.模型迁移&#xff08;Pa…...

【iOS】push和present的区别

【iOS】push和present的区别 文章目录 【iOS】push和present的区别前言pushpop presentdismiss简单小demo来展示dismiss和presentdismiss多级 push和present的区别区别相同点 前言 在iOS开发中&#xff0c;我们经常性的会用到界面的一个切换的问题&#xff0c;这里我们需要理清…...

在Linux服务器上添加用户并设置自动登录

需要在Linux服务器上添加一个新用户&#xff0c;可以使用以下命令 # 这个命令会创建一个新的用户账户&#xff0c;默认情况下不会设置密码&#xff0c;不会在 /home 目录下为新用户创建home目录&#xff1a; # sudo useradd 用户名 # # 如果希望同时为新用户创建家目录&#…...

网站被爬,数据泄露,如何应对不断强化的安全危机?

近年来&#xff0c;众多传统零售商和互联网企业借助大数据、人工智能等先进技术手段&#xff0c;通过场景化设计、优化客户体验、融合线上线下渠道&#xff0c;推动了网络电商行业的消费方式变革&#xff0c;成为电商领域新的增长动力。 但值得注意的是&#xff0c;网络电商带来…...

为什么HTTPS会引入SSL/TLS协议

这时我面试遇到过的问题,整理了一下,希望对大家有帮助! 祝大家秋招顺利! 首先 SSL/TLS 协议通过使用数字证书来实现服务器身份认证, 当用户访问一个 HTTPS 网站时,浏览器会验证服务器的数字证书, 1.首先他对验证整证书是否在有效期 2.其次他会看证书中的服务器域名…...

Spring AOP,通知使用,spring事务管理,spring_web搭建

spring AOP AOP概述 AOP面向切面编程是对面向对象编程的延续&#xff08;AOP &#xff08;Aspect Orient Programming&#xff09;,直译过来就是 面向切面编程,AOP 是一种编程思想&#xff0c;是面向对象编程&#xff08;OOP&#xff09;的一种补充。&#xff09; 面向切面编…...

PHP无缝对接预订无忧场馆预订系统小程序源码

无缝对接&#xff0c;预订无忧 —— 场馆预订系统&#xff0c;让每一次活动都完美启航&#xff01; 一、告别繁琐流程&#xff0c;预订从未如此简单 你是否曾经为了预订一个合适的场馆而焦头烂额&#xff1f;繁琐的咨询、确认、支付流程&#xff0c;让人心力交瘁。但现在&…...

Unet改进30:添加CAA(2024最新改进方法)|上下文锚定注意模块来捕获远程上下文信息。

本文内容:在不同位置添加CAA注意力机制 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 遥感图像中的目标检测经常面临一些日益严峻的挑战,包括目标尺度的巨大变化和不同的测距环境。先前的方法试图通过大核卷积或扩展卷积来扩展主干的空间感受野来解决这…...

OpenAI震撼发布最强模型o1!强化学习突破LLM推理极限

OpenAI新模型无预警上新&#xff1a; o1系列&#xff0c;可以进行通用复杂推理&#xff0c;每次回答要花费更长时间思考。 在解决博士水平的物理问题时&#xff0c;GPT-4o还是“不及格”59.5分&#xff0c;o1一跃来到“优秀档”&#xff0c;直接干到92.8分&#xff01; 没错…...

速通GPT-2:Language Models are Unsupervised Multitask Learners全文解读

文章目录 GPT系列论文速通引言总览GPT和GPT-2区别Abstract1. 概括2. 具体分析 Introduction1. 概括2. 具体分析当前机器学习系统的局限性希望构建通用型系统数据集与任务通用性缺乏的原因 Approach1. 概括与要点2. 原文阅读翻译3. 具体分析论文核心Training DatasetInput Repre…...

Python 最小公倍数计算器:从基础到应用

目录 引言数学背景 什么是最小公倍数(LCM)计算LCM的方法Python基础 Python简介Python安装和设置使用Python计算最小公倍数 理论基础Python实现详细代码解析 辅助函数LCM计算函数最小公倍数的应用 工作中的应用场景日常生活中的应用场景优化与扩展 代码优化处理多个数字进阶话…...

网络学习-eNSP配置路由器

#PC1网关&#xff1a;192.168.1.254 #PC3网关&#xff1a;192.168.3.254 #PC4网关&#xff1a;192.168.4.254# 注&#xff1a;路由器接口必须配置不同网段IP地址 <Huawei>system-view Enter system view, return user view with CtrlZ. #给路由器两个接口配置IP地址 [Hua…...

在 React 中,如何使用 Context API 来实现跨组件的通信?

在 React 中&#xff0c;Context API 提供了一种方式&#xff0c;允许你在组件树中传递数据&#xff0c;而无需在每个层级手动传递 props。这对于实现跨组件通信非常有用&#xff0c;特别是当你需要在多个组件间共享状态或函数时。 以下是如何使用 Context API 来实现跨组件通…...

【基础算法总结】位运算

目录 一&#xff0c;常见位运算操作总结二&#xff0c;算法原理和代码实现191.位1的个数338.比特位计数461.汉明距离面试题01.01.判断字符是否唯一268.丢失的数字371.两整数之和136.只出现一次的数字137.只出现一次的数字II260.只出现一次的数据III面试题17.19.消失的两个数字 …...