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

建造者模式 rust和java的实现

文章目录

    • 建造者模式
      • 介绍
        • 优点
        • 缺点
        • 使用场景
      • 实现
      • java
      • rust
    • rust代码仓库

建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

介绍

  • 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
  • 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
  • 关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
  • 应用实例: 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。

建造者模式的 UML 图
在这里插入图片描述

java

步骤 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 接口的抽象类,该类提供了默认的功能,实现汉堡抽象和冷饮抽象的包装类。

Burger.java

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

ColdDrink.java

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

步骤 4
创建扩展了 Burger 和 ColdDrink 的实体类。

VegBurger.java

public class VegBurger extends Burger {@Overridepublic float price() {return 25.0f;}@Overridepublic String name() {return "Veg Burger";}
}

ChickenBurger.java

public class ChickenBurger extends Burger {@Overridepublic float price() {return 50.5f;}@Overridepublic String name() {return "Chicken Burger";}
}

Coke.java


public class Coke extends ColdDrink {@Overridepublic float price() {return 30.0f;}@Overridepublic String name() {return "Coke";}
}

Pepsi.java


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

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

Meal.java

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 对象。

MealBuilder.java

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
BuiderPatternDemo 使用 MealBuilder 来演示建造者模式(Builder Pattern)。

BuilderPatternDemo.java

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

rust

因为rust的类支持组合式而不支持继承,在进行建造者构件时比java更加容易,rust的trait是支持继承的。

// rsut trait不支持重名
pub trait Item {fn name(&self)->String;   fn price(&self)->f32;   fn packing(&self)->String;
}// 汉堡实体类
struct ChickenBurger;
impl Item for ChickenBurger {fn name(&self)->String {String::from("ChickenBurger")}fn price(&self)->f32 {35.0}fn packing(&self)->String {String::from("Wrappper")}}  
struct VegBurger;
impl Item for VegBurger {fn name(&self)->String {String::from("Pepsi")}fn price(&self)->f32 {35.0}fn packing(&self)->String {String::from("Wrappper")}
}  // 饮料实体类
struct Pepsi;impl Item for Pepsi {fn name(&self)->String {String::from("Pesi")}fn price(&self)->f32 {35.0}fn packing(&self)->String {String::from("Bottle")}
}  
struct Coke;impl Item for Coke {fn name(&self)->String {String::from("Coke")}fn price(&self)->f32 {35.0}fn packing(&self)->String {String::from("Bottle")}
}  struct Meal {items:Vec<Box<dyn Item>>,
}
impl Meal {fn add_item<T>(&mut self,item:Box<dyn Item>) {self.items.push(item)}fn get_cost(&self)->f32{// 普通函数实现// let mut sum:f32=0.0; // for i in self.items.iter()  {//     let price = i.price();//     sum+=price;// }// sum// 函数sjiself.items.iter().fold(0.0, |acc, x| acc + x.price())}fn  show_items(&self){for  i in self.items.iter() {println!("{}",i.name());println!("{}",i.packing());println!("{}",i.price());}}
}
// 添加建造者
struct MealBuilder {}
impl  MealBuilder {fn prepareVegMeal()->Meal{let mut meal=Meal{items:Vec::new()};meal.add_item::<Box<dyn Item>>(Box::new(VegBurger{}));meal.add_item::<Box<dyn Item>>(Box::new(Coke{}));meal}fn prepareNonVegMeal()->Meal{let mut meal=Meal{items:Vec::new()};meal.add_item::<Box<dyn Item>>(Box::new(ChickenBurger{}));meal.add_item::<Box<dyn Item>>(Box::new(Pepsi{}));meal}
}
fn main() {let m=MealBuilder::prepareVegMeal();println!(" Veg Meal");m.show_items();println!("Total Cost : {}",m.get_cost());let m=MealBuilder::prepareNonVegMeal();println!(" \n\nNon-Veg Meal");m.show_items();println!("Total Cost : {}",m.get_cost());
}

rust代码仓库

https://github.com/onenewcode/design.git
本教程项目在bin文件夹下的builder.rs文件中

相关文章:

建造者模式 rust和java的实现

文章目录 建造者模式介绍优点缺点使用场景 实现javarust rust代码仓库 建造者模式 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍…...

书写Prompt的经验总结

首先最重要的一点是Prompt无法全部模型都通用&#xff0c;可能你的Prompt在ChatGPT中使用很好&#xff0c;迁移到ChatGLM就不行了。不知道未来是否会出现Prompt的跨平台。 首先书写Prompt要明确告诉模型要做什么&#xff0c;而不是告诉它不要做什么。还要保证精简&#xff0c;…...

WebSocket实时应用

在开发一些前端页面的时候&#xff0c;总是能接收到这样的需求&#xff1a;如何保持页面并实现自动更新数据呢&#xff1f;以往的常规做法&#xff0c;是前端使用定时轮询后端接口&#xff0c;获取响应后重新渲染前端页面&#xff0c;这种做法虽然能达到类似的效果&#xff0c;…...

从零开始搭建React+TypeScript+webpack开发环境-基于lerna的webpack项目工程化改造

项目背景 在实际项目中&#xff0c;我们的前端项目往往是一个大型的Webpack项目&#xff0c;结构较为复杂。项目根目录下包含了各种配置文件、源代码、以及静态资源&#xff0c;整体布局相对扁平。Webpack的配置文件分散在不同的部分&#xff0c;包括入口文件、输出目录、加载…...

网络监控系统和防火墙的区别有哪些?

现如今&#xff0c;市面上保护企业网络安全的设备有很多&#xff0c;其中使用最多的当属网络监控系统和防火墙。 网络监控系统就是通过网页内容的自动采集处理、敏感词过滤、智能聚类分类、主题检测、专题聚焦、统计分析等多个环节&#xff0c;实现相关网络舆情监督管理的需要…...

刷题学习记录BUUCTF

[极客大挑战 2019]RCE ME1 进入环境直接就有代码 <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("This is too Long.");}if(preg_match("/[A-Za-z0-9]/",$code)){die("NO.");}eval($co…...

Linux imu6ull驱动- led

一、GPIO模块结构 开始来啃手册了&#xff0c;打开我们的imx6ull手册。本章我们编写的是GPIO的&#xff0c;打开手册的第28章&#xff0c;这一章就有关于IMX6ULL 的 GPIO 模块结构。 mx6ull一共有5 组 GPIO&#xff08;GPIO1&#xff5e;GPIO5&#xff09; GPIO1 有 32 个引脚&…...

【 云原生 | K8S 】Kubernetes 概述

Kubernetes 概述 1 K8S 是什么&#xff1f; K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS&#xff1a;“嘛&#xff0c;写全称也太累了吧&#xff0c;不如整个缩写”。 作用&#xff1a; 用于自动部署、扩展和管理“容器化&#xff08;containerized&#xff09;应用…...

边缘计算多角色智能计量插座:用电监测和资产管理的未来智能化引擎

目前主流的智能插座涵盖了红外遥控&#xff08;控制空调和电视等带有红外标准的电器&#xff09;&#xff0c;配备着测温、测湿等仓库应用场景&#xff0c;配备了人体红外或者毫米波雷达作为联动控制&#xff0c;但是大家有没有思考一个问题&#xff0c;就是随着对接的深入&…...

mysql隐式转换转换引起的bug

生产环境中遇到一个情况情况 &#xff0c;过滤数据发现过滤不掉相关值情况&#xff0c;具体情况如下 原始数据&#xff1a; CREATE TABLE test (id bigint(11) NOT NULL AUTO_INCREMENT COMMENT 自增id,subject_id bigint(11) NOT NULL DEFAULT 0 COMMENT 主题id,subject_nam…...

【Python】gevent模块实现协程模拟高并发

Python中GIL的存在&#xff0c;导致多线程一直不是很好用&#xff0c;相形之下&#xff0c;协程的优势就更加突出了。 Python通过yield提供了对协程的基本支持&#xff0c;但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。 gevent是第三方库&#xff0c;通过gr…...

leetcode:2485. 找出中枢整数(python3解法)

难度&#xff1a;简单 给你一个正整数 n &#xff0c;找出满足下述条件的 中枢整数 x &#xff1a; 1 和 x 之间的所有元素之和等于 x 和 n 之间所有元素之和。 返回中枢整数 x 。如果不存在中枢整数&#xff0c;则返回 -1 。题目保证对于给定的输入&#xff0c;至多存在一个中…...

asp.net core mvc之模型绑定、特性约束模型绑定、模型验证(服务器/客户端/远程)

一、不用模型绑定 数据类型都是string 1、UserController.cs public class UserController : Controller {public IActionResult Register(){return View();}[HttpPost]public IActionResult DoRegister(){//不用模型绑定 以前的方法取表单数据或Url的参数//数据类型都是s…...

AI诈骗防范:保护数字社会的安全前线

引言&#xff1a; 在当今数字化的时代&#xff0c;人工智能技术在各个领域都展现了巨大的潜力&#xff0c;然而&#xff0c;正是这些技术的广泛应用也催生了新的安全隐患。近期&#xff0c;AIGC在聊天、写作、绘画、编程等领域表现出色&#xff0c;但也被用于“AI换脸”、“AI换…...

(待完善)python学习参考手册

这里写目录标题 观前浅谈:学习路线 :学习心得笔记:Step1:简单但一问不知怎么的组织语言去回答的小问题:什么是提示符?python解释器是什么?请正在阅读本文的朋友,安装一下PyCharm以及如何进行科学的省钱:Python中的命令行模式和交互模式的区别是什么?请正在阅读本文的朋友安装…...

STM32-HAL库09-CAN通讯(loopback模式)

一、所用材料&#xff1a; STM32F103C6T6最小系统板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 串口调试助手 二、所学内容&#xff1a; 初步学习如何使用STM32的CAN通讯功能&#xff0c;在本章节主要达到板内CAN通讯的效果&#xff0c;即32发送CAN信息再在CAN接收…...

jsvascript使用dhtmlXTreeObject的loadJSONObject绘制目录树

文章目录 1&#xff0c;引入dhtmlXTreeObject的css和js文件2&#xff0c;创建一棵目录树2.1&#xff0c;let tree new dhtmlXTreeObject(id-dhtmltree-0, "100%", "100%", 0);2.2&#xff0c;设置图片根目录&#xff08;后续使用到的图片都是相对于该目录…...

LeetCode 17. 电话号码的字母组合 中等

题目 - 点击直达 1. 17. 电话号码的字母组合 中等1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 3. 知识与收获 1. 17. 电话号码的字母组合 中等 1. 题目详情 1. 原题链接 LeetCode 17. 电话号码的字母组合 中等 2. 题目要…...

《GPT与AI助手:技术进步与就业前景》

随着人工智能的迅速发展&#xff0c;像GPT&#xff08;Generative Pre-trained Transformer&#xff09;这样的自然语言处理技术已经广泛应用于各个领域&#xff0c;各个互联网公司也纷纷推出了自己的AI助手来帮助创作、交流和解决问题。这一技术的广泛应用引发了一系列关于就业…...

线性代数 | 矩阵运算 加减 数乘 矩阵的幂运算

文章目录 1 矩阵加减和数乘2 矩阵与矩阵的乘法2.1 相乘条件&#xff1a;看中间&#xff0c;取两头2.2 相乘计算方法 3 矩阵的幂3.1 观察归纳法3.2 邻项相消法3.3 化为对角 4 判断是否可逆&#xff08;证明题或者要求求出逆矩阵&#xff09;4.1 直接观察4.2 由定义式推得4.2.1 待…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...