java设计模式 建造者设计模式

建造者模式(Builder Pattern)是一种设计模式,用于将复杂对象的构建与其表示分离,以便同样的构建过程可以创建不同的表示。以下是建造者模式的一个案例分析,以及在Java中的实现。

### 案例分析

假设我们要设计一个用于创建汉堡的系统。一个汉堡可能包含多种配料,比如面包、肉饼、生菜、番茄、洋葱、奶酪和酱料。不同的顾客可能需要不同的配料组合,因此我们希望设计一个灵活的系统来构建汉堡。

### 角色

1. **产品(Product)**:在本例中,产品就是汉堡。
2. **建造者(Builder)**:定义创建产品的方法,提供一个返回产品类型的方法。
3. **指导者(Director)**:负责使用建造者对象来创建一个产品对象。

### Java实现

首先,我们定义汉堡的组成部分:

```java
 

public class Burger {private String bread;private String meat;private String lettuce;private String tomato;private String onion;private String cheese;private String sauce;// Constructorpublic Burger(String bread, String meat, String lettuce, String tomato, String onion, String cheese, String sauce) {this.bread = bread;this.meat = meat;this.lettuce = lettuce;this.tomato = tomato;this.onion = onion;this.cheese = cheese;this.sauce = sauce;}// Getters and setters// ...
}


```

然后,我们定义建造者接口:

```java

public interface BurgerBuilder {void setBread(String bread);void setMeat(String meat);void setLettuce(String lettuce);void setTomato(String tomato);void setOnion(String onion);void setCheese(String cheese);void setSauce(String sauce);Burger getBurger();
}


```

接下来,实现建造者接口:

```java

public class BurgerBuilderImpl implements BurgerBuilder {private Burger burger;public BurgerBuilderImpl() {burger = new Burger(null, null, null, null, null, null, null);}@Overridepublic void setBread(String bread) {burger.bread = bread;}@Overridepublic void setMeat(String meat) {burger.meat = meat;}// ... other set methods@Overridepublic Burger getBurger() {return burger;}
}


```

最后,我们定义指导者:

```java

public class BurgerDirector {private BurgerBuilder builder;public BurgerDirector(BurgerBuilder builder) {this.builder = builder;}public Burger constructBurger() {// 指导者指导建造者如何构建汉堡builder.setBread("Wheat");builder.setMeat("Beef");builder.setLettuce("Fresh");builder.setTomato("Fresh");builder.setOnion("Fresh");builder.setCheese("Cheddar");builder.setSauce("Tomato");return builder.getBurger();}
}


```

### 使用建造者模式

```java

public class Client {public static void main(String[] args) {BurgerDirector director = new BurgerDirector(new BurgerBuilderImpl());Burger burger = director.constructBurger();// 打印汉堡的配料System.out.println("Burger created with: ");System.out.println("Bread: " + burger.bread);System.out.println("Meat: " + burger.meat);// ... 其他配料}
}


```

通过这种方式,建造者模式允许我们通过指导者来指导建造者对象,创建出满足不同顾客需求的汉堡,而不需要每次都重新编写构建逻辑。建造者模式在创建复杂对象时非常有用,尤其是在对象的创建过程需要通过多个步骤进行时。

在上一个回答中,我们已经实现了建造者模式的一个基本例子,包括定义产品、建造者接口、具体的建造者实现以及指导者。现在,让我们继续深入探讨建造者模式的一些高级应用和可能的改进。

### 高级应用和改进

1. **更灵活的建造者**:在实际应用中,建造者可以提供更多的灵活性,比如允许用户自定义配料,或者提供一系列预定义的配料选项。

2. **异步构建**:如果创建对象的过程非常耗时,可以考虑将建造过程设计为异步的,这样就不会阻塞主线程。

3. **线程安全**:如果建造者对象可能会被多个线程访问,需要确保建造者是线程安全的。

4. **扩展性**:建造者模式可以很好地扩展,以支持创建不同类型的产品。只需添加新的具体建造者实现即可。

5. **使用命令模式**:在指导者中,可以使用命令模式来封装构建过程的每一步,这样可以更灵活地控制构建过程。

### 改进后的建造者实现

让我们对建造者实现进行一些改进,使其更加灵活和可扩展:

```java

public interface BurgerBuilder {// 允许用户自定义配料BurgerBuilder addBread(String bread);BurgerBuilder addMeat(String meat);// ... 其他配料方法// 构建最终产品Burger build();
}public class BurgerBuilderImpl implements BurgerBuilder {private Burger burger;public BurgerBuilderImpl() {burger = new Burger(null, null, null, null, null, null, null);}@Overridepublic BurgerBuilder addBread(String bread) {burger.bread = bread;return this; // 返回建造者本身,以支持链式调用}@Overridepublic BurgerBuilder addMeat(String meat) {burger.meat = meat;return this;}// ... 其他配料方法@Overridepublic Burger build() {return new Burger(burger.bread,burger.meat,// ... 其他配料);}
}
```### 使用改进后的建造者模式```java
public class Client {public static void main(String[] args) {BurgerDirector director = new BurgerDirector();BurgerBuilder builder = new BurgerBuilderImpl();Burger burger = director.constructBurger(builder).addBread("Wheat").addMeat("Beef")// ... 添加其他配料.build();// 打印汉堡的配料System.out.println("Burger created with: ");System.out.println("Bread: " + burger.bread);System.out.println("Meat: " + burger.meat);// ... 其他配料}
}


```

在这个改进的例子中,我们使用了链式调用来简化配料的添加过程,使得构建汉堡更加直观和方便。同时,我们也可以使用不同的建造者实现来创建不同类型的汉堡,而不需要修改指导者或产品类。

建造者模式是一种非常有用的设计模式,它可以帮助我们创建复杂的对象,同时保持代码的清晰和可维护性。通过合理地应用和扩展建造者模式,我们可以构建出更加灵活和强大的系统。

在上一个回答中,我们已经对建造者模式进行了一些改进,使其更加灵活和易于使用。接下来,我将提供一些额外的思考点和可能的进一步改进方向。

进一步改进方向

  1. 参数验证:在建造者模式中,可以加入参数验证来确保传入的配料是有效的。

  2. 默认值:为建造者提供默认值,以便在用户没有指定某些配料时使用。

  3. 限制条件:在某些情况下,可能需要对配料进行限制,比如某些配料不能同时选择。

  4. 日志记录:在建造过程中记录日志,以便于调试和追踪构建过程。

  5. 构建步骤的撤销:提供撤销功能,允许用户回退到之前的构建步骤。

  6. 构建过程的暂停和恢复:在某些情况下,可能需要暂停构建过程,稍后再继续。

  7. 构建过程的并行化:如果构建过程可以分解为多个独立的任务,可以考虑使用并行处理来提高效率。

  8. 构建结果的缓存:对于频繁请求的相同产品,可以考虑缓存构建结果以提高性能。

改进后的建造者模式实现

让我们在建造者实现中加入一些参数验证和默认值:

public interface BurgerBuilder {BurgerBuilder addBread(String bread);BurgerBuilder addMeat(String meat);// ... 其他配料方法Burger build();
}public class BurgerBuilderImpl implements BurgerBuilder {private Burger burger;public BurgerBuilderImpl() {burger = new Burger("White", // 默认面包"Chicken", // 默认肉类"", // 默认生菜"", // 默认番茄"", // 默认洋葱"", // 默认奶酪""  // 默认酱料);}@Overridepublic BurgerBuilder addBread(String bread) {if (bread == null || bread.isEmpty()) {throw new IllegalArgumentException("Bread cannot be null or empty");}burger.bread = bread;return this;}@Overridepublic BurgerBuilder addMeat(String meat) {if (meat == null || meat.isEmpty()) {throw new IllegalArgumentException("Meat cannot be null or empty");}burger.meat = meat;return this;}// ... 其他配料方法@Overridepublic Burger build() {// 这里可以加入更多的验证逻辑return new Burger(burger.bread,burger.meat,// ... 其他配料);}
}

使用改进后的建造者模式

public class Client {public static void main(String[] args) {try {BurgerBuilder builder = new BurgerBuilderImpl();Burger burger = builder.addBread("Wheat").addMeat("Beef")// ... 添加其他配料.build();// 打印汉堡的配料System.out.println("Burger created with: ");System.out.println("Bread: " + burger.bread);System.out.println("Meat: " + burger.meat);// ... 其他配料} catch (IllegalArgumentException e) {System.out.println("Error building burger: " + e.getMessage());}}
}

在这个改进的例子中,我们为建造者添加了参数验证,确保用户传入的配料是有效的。同时,我们也为建造者提供了一些默认值,以便在用户没有指定某些配料时使用。

通过这些改进,建造者模式变得更加健壮和易于使用。它不仅提供了更高的灵活性,还提高了代码的可维护性和可读性。在实际应用中,根据具体需求,还可以继续对建造者模式进行定制和优化。

 

在前面的讨论中,我们已经对建造者模式进行了详细的探讨,包括其基本概念、实现方式以及如何进行改进。接下来,我将提供一些额外的思考点,以及如何在实际项目中应用建造者模式。

实际应用中的考虑

  1. 理解需求:在应用建造者模式之前,需要充分理解业务需求,确定是否需要如此复杂的构建过程。

  2. 避免过度设计:建造者模式可以提高代码的可读性和可维护性,但也可能导致过度设计。只有在确实需要构建复杂对象时,才应该使用建造者模式。

  3. 性能考量:建造者模式可能会增加一些性能开销,特别是在需要频繁创建对象的情况下。在性能敏感的应用中,需要仔细权衡使用建造者模式的利弊。

  4. 代码复用:建造者模式可以提高代码的复用性,但也需要确保各个建造者实现之间的一致性,避免出现不一致的行为。

  5. 文档和示例:在使用建造者模式时,提供清晰的文档和示例代码,帮助其他开发者理解和使用建造者模式。

  6. 测试:对建造者模式进行充分的测试,包括单元测试和集成测试,确保其正确性和稳定性。

  7. 版本控制:如果产品类可能会发生变化,需要考虑如何管理不同版本的建造者和产品。

建造者模式与其他模式的结合

建造者模式可以与其他设计模式结合使用,以解决更复杂的问题:

  1. 与工厂方法模式结合:可以使用工厂方法来创建建造者对象,进一步封装对象的创建过程。

  2. 与原型模式结合:如果创建对象的过程非常耗时,可以使用原型模式来克隆已有的对象,而不是从头开始构建。

  3. 与命令模式结合:可以使用命令模式来封装建造过程中的每一步操作,实现更灵活的构建过程。

  4. 与模板方法模式结合:可以使用模板方法模式来定义建造过程的骨架,将一些步骤留给子类实现。
     

    结语

    建造者模式是一种强大的设计模式,它可以帮助我们构建复杂的对象,同时保持代码的清晰和可维护性。在实际应用中,需要根据具体需求来决定是否使用建造者模式,以及如何进行合理的设计和优化。

    建造者模式并不是万能的,它也有其适用场景和限制。在设计软件时,应该综合考虑各种因素,选择最合适的设计模式和实现方式。通过不断学习和实践,我们可以更好地掌握建造者模式,以及如何将其应用到实际项目中。

 

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

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

相关文章

单元测试与集成测试:软件质量的双重保障

目录 概述 单元测试 集成测试 单元测试的方法 白盒测试 黑盒测试 白盒测试的方法和用例设计 代码审查 集成测试 单元测试工具 结语 在软件开发中,测试是一个不可或缺的环节,它能够帮助我们发现和修复缺陷,确保软件的质量和可靠性。…

基于UDP的网络客户端和服务端模型IO函数

服务器端 udp_server.c #include <stdio.h> // 引入标准输入输出库 #include <sys/types.h> // 引入基本系统数据类型 #include <sys/socket.h> // 引入socket编程相关的库 #include <netinet/in.h> // 引入网络…

2024年3月 青少年等级考试机器人理论真题二级

202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车&#xff0c;用左右两个电机分别控制左右车轮&#xff0c;左侧电机转速是100rpm&#xff0c;右侧电机转速是50rpm&#xff0c;则此机器小车&#xff1f;&#xff08; &#xff09; A&#xff1a;原地右转 B&am…

华企盾DSC数据防泄密软件有哪些水印功能?

在企业数据安全领域&#xff0c;水印技术是一种重要的信息保护策略&#xff0c;用于防止数据泄露和确保信息的原始性和完整性。根据回顾的资料&#xff0c;以下是企业中常用的几种水印技术&#xff1a; 屏幕浮水印&#xff1a;这种水印能够在用户的屏幕上显示公司的标志或者其他…

Golang SDK安装

windows环境安装 1.链接: 下载地址 2.安装SDK 检查环境变量&#xff1a; 3.开启go modules,命令行执行一下命令&#xff1a; go env -w GO111MODULEon4.设置国内代理&#xff0c;命令行执行一下命令&#xff1a; go env -w GOPROXYhttps://proxy.golang.com.cn,https:/…

C#之partial关键字

在C#中&#xff0c;partial关键字用于声明一个类、结构体、接口或方法的分部定义。这意味着可以将一个类或其他类型的定义分成多个部分&#xff0c;这些部分可以在同一个命名空间或程序集中的多个源文件中进行定义。当编译器编译这些部分时&#xff0c;会将它们合并成一个单独的…

打印机 ansible配置dhcp和打印机

部署dhcp服务器 主机发送Discover报文 目标为广播地址 同一网段的dhcp收到报文后&#xff0c;dhcp响应一个offer报文 offer报文&#xff1a;dhcp自己的ip地址。和客户端ip以及使用周期&#xff0c;和客户端ip网络参数 最后主机单独发一个request报文 给那个选择的dhcp服务器 &…

JUC下的ThreadLocalRandom详解

ThreadLocalRandom 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个随机数生成器类&#xff0c;它是从Java 7开始引入的。相较于传统的Math.random()或Random类&#xff0c;ThreadLocalRandom更适用于多线程环境&#xff0c;因为它为每个线程维护了一个…

福建医疗器械展/2024厦门国际医疗器械展览会重磅来袭

2024中国&#xff08;厦门&#xff09;国际医疗器械展览会 时 间&#xff1a;2024年11月1-3日 November 1-3, 2024 地 点&#xff1a;厦门国际会展中心 Xiamen International Conference & Exhibition Center ​ ◆组织机构 主办单位&#xff1a; 中国技术市场协会医…

Blazor入门-调用js+例子

参考&#xff1a; Blazor入门笔记&#xff08;3&#xff09;-C#与JS交互 - 半野 - 博客园 https://www.cnblogs.com/zxyao/p/12638233.html Blazor项目如何调用js文件_blazor加载js-CSDN博客 https://blog.csdn.net/bdbox/article/details/135438411 本地环境&#xff1a;win1…

六西格玛绿带培训:企业变革的催化剂,个人成长的助推器!

六西格玛绿带培训不仅是一套系统的管理方法&#xff0c;更是一种追求卓越、持续改进的文化和思维方式。它强调以数据为基础&#xff0c;通过科学的分析和决策&#xff0c;实现质量的飞跃和成本的优化。对于企业来说&#xff0c;六西格玛绿带培训能够帮助企业建立可靠的质量管理…

Spring STOMP-消息代理

简单的消息代理 内置的简单消息代理会处理来自客户端的订阅请求&#xff0c;将请求消息存储在内存中&#xff0c;并广播消息给匹配destination的连接客户端。代理支持路径式destination&#xff0c;包括订阅Ant风格的destinations模式。 应用程序也可以使用点分隔&#xff08;…

【车辆安全管理】风险预测

近期又发生了很多车辆事故&#xff0c; https://news.sina.com.cn/s/2024-05-13/doc-inavapur2236074.shtml 其实都是可以避免的&#xff0c;如果车辆有很好的自动减速系统&#xff0c;如特斯拉的FSD系统&#xff0c; 特斯拉的FSD&#xff08;Full-Self Driving&#xff09;…

11、24年--信息技术发展——新一代信息技术及应用

1、物联网 物联网(The Internet of Things)是指通过信息传感设备,按约定的协议将任何物品与互联网相连接,进行信息交换和通信,以实现智能化识别、定位、跟踪、监控和管理的网络。 1.1 技术基础 物联网架构可分为三层:感知层、网络层和应用层。感知层由各种传感器…

AI翻唱+视频剪辑全流程实战

目录 一、AI翻唱之模型训练 &#xff08;1&#xff09;模型部署 &#xff08;2&#xff09;数据集制作——搜集素材 &#xff08;3&#xff09;数据集制作——提升音频质量 方法一&#xff1a;使用RVC提供的音频处理功能。 方法二&#xff1a;可以使用音频剪辑工具Ad…

我是如何免费抵御一个多月的 DDos/CC 攻击的?

今天明月给大家详细分享一下我的博客是如何免费抵御了长达一个多月的 DDos/CC 攻击的&#xff0c;在【现在 DDos/CC 攻击门槛低的可怕&#xff01;】一文里明月就说过现在 DDos/CC 攻击几乎是没有门槛的&#xff0c;任何一个老鼠屎在群里看到你的博客都可以轻松便捷的发动一次 …

R语言数据分析案例-股票题目分析

Value at Risk&#xff08;VaR&#xff09;是一种统计技术&#xff0c;用于量化投资组合在正常市场条件下可能遭受的最大潜在损失。它是风险管理和金融领域中一个非常重要的概念。VaR通常以货币单位表示&#xff0c;用于估计在给定的置信水平和特定时间范围内&#xff0c;投资组…

宝塔助手v1.4.1/手机操控云服务器的神器软件

宝塔助手是以宝塔Linux面板提供的API开发的一款可以随时随地管理服务器的APP。通过这款APP你可以随时随地的查看一台或多台服务器的运行情况&#xff0c;对服务器网站、FTP、数据库、文件进行管理。内置文件编辑器&#xff0c;可以对网站文件进行修改。 链接&#xff1a;https:…

Java PowerMockito static方法/new对象/public方法/private方法/public属性/private属性

Java PowerMockito static方法/new对象/public方法/private方法/public属性/private属性 1 变量Mock1.1 公有变量1.2 私有变量1.3 公有静态变量1.4 私有静态变量 2 方法Mock2.1 共有方法2.2 私有方法2.3 共有静态方法2.4 共有最终方法 3 new对象Mock3.1 共有方法 1 变量Mock p…

【ARM Cortex-M 系列 2.2 -- Cortex-M7 单步调试原理及实现详细介绍】

请阅读【嵌入式开发学习必备专栏】 文章目录 单步调试概述单步执行原理Debug stepping control using the DHCSR 紧接上篇文章 【ARM Cortex-M 系列 2.1 – Cortex-M7 Debug system registers】 单步调试概述 在ARMv7-M架构中&#xff0c;通过使用单步调试&#xff08;Haltin…