设计模式——构建者模式

server/2024/10/9 8:55:07/

提问:通过对比使用构建者模式和不使用构建者模式,以更好的说明构建者模式的作用
GPT:当然,我很乐意通过对比来帮助您更好地理解构建者模式的作用。让我们以一个复杂对象的创建为例,比如一个计算机(Computer)对象,它有多个可配置的部件。

不使用构建者模式

首先,让我们看看不使用构建者模式时,我们如何创建一个 Computer 对象:

public class Computer {private String CPU;private String RAM;private String storage;private String GPU;private String operatingSystem;// 构造函数public Computer(String CPU, String RAM, String storage, String GPU, String operatingSystem) {this.CPU = CPU;this.RAM = RAM;this.storage = storage;this.GPU = GPU;this.operatingSystem = operatingSystem;}// Getters...
}// 客户端代码
public class Client {public static void main(String[] args) {Computer computer = new Computer("Intel i7", "16GB", "512GB SSD", "NVIDIA RTX 3070", "Windows 10");}
}

问题

  1. 构造函数参数过多,可读性差。
  2. 如果某些参数是可选的,需要创建多个构造函数或使用setter方法。
  3. 参数的顺序很重要,容易出错。
  4. 如果要添加新的属性,需要修改构造函数,这违反了开闭原则。

使用构建者模式

现在,让我们看看使用构建者模式如何改进这个情况:

public class Computer {private String CPU;private String RAM;private String storage;private String GPU;private String operatingSystem;private Computer(Builder builder) {this.CPU = builder.CPU;this.RAM = builder.RAM;this.storage = builder.storage;this.GPU = builder.GPU;this.operatingSystem = builder.operatingSystem;}// Getters...public static class Builder {private String CPU;private String RAM;private String storage;private String GPU;private String operatingSystem;public Builder CPU(String CPU) {this.CPU = CPU;return this;}public Builder RAM(String RAM) {this.RAM = RAM;return this;}public Builder storage(String storage) {this.storage = storage;return this;}public Builder GPU(String GPU) {this.GPU = GPU;return this;}public Builder operatingSystem(String operatingSystem) {this.operatingSystem = operatingSystem;return this;}public Computer build() {return new Computer(this);}}
}// 客户端代码
public class Client {public static void main(String[] args) {Computer computer = new Computer.Builder().CPU("Intel i7").RAM("16GB").storage("512GB SSD").GPU("NVIDIA RTX 3070").operatingSystem("Windows 10").build();}
}

优势

  1. 可读性提高:每个参数的含义都很清晰。
  2. 灵活性增强:可以只设置需要的参数,其他参数可以有默认值。
  3. 参数顺序不重要:可以以任意顺序设置参数。
  4. 不可变性:一旦 Computer 对象被创建,就不能被修改。
  5. 易于扩展:如果需要添加新的属性,只需在 Builder 中添加新的方法,不需要修改 Computer 类。

进一步的优势展示

假设我们现在需要添加一些可选的配置,比如网络适配器和声卡:

public class Computer {// ... 之前的属性private String networkAdapter;private String soundCard;private Computer(Builder builder) {// ... 之前的赋值this.networkAdapter = builder.networkAdapter;this.soundCard = builder.soundCard;}// Getters...public static class Builder {// ... 之前的属性private String networkAdapter;private String soundCard;// ... 之前的方法public Builder networkAdapter(String networkAdapter) {this.networkAdapter = networkAdapter;return this;}public Builder soundCard(String soundCard) {this.soundCard = soundCard;return this;}public Computer build() {return new Computer(this);}}
}// 客户端代码
public class Client {public static void main(String[] args) {Computer computer1 = new Computer.Builder().CPU("Intel i7").RAM("16GB").storage("512GB SSD").GPU("NVIDIA RTX 3070").operatingSystem("Windows 10").networkAdapter("Intel Wi-Fi 6").build();Computer computer2 = new Computer.Builder().CPU("AMD Ryzen 9").RAM("32GB").storage("1TB NVMe SSD").GPU("AMD Radeon RX 6800").operatingSystem("Linux").soundCard("Creative Sound Blaster").build();}
}

在这个例子中,构建者模式的优势更加明显:

  1. 处理可选参数:我们可以轻松地添加可选的配置,而不需要创建多个构造函数或使用大量的setter方法。
  2. 创建不同配置的对象:我们可以轻松地创建具有不同配置的对象,而不需要记住复杂的参数顺序。
  3. 代码可读性:即使有很多参数,代码仍然保持清晰和易读。

总结

通过这个对比,我们可以看到构建者模式的主要作用:

  1. 提高可读性:通过方法链的方式设置参数,使得代码更加清晰易读。
  2. 处理多参数:优雅地处理大量参数,特别是当有些参数是可选的时候。
  3. 保证不可变性:一旦对象被创建,就不能被修改,这在并发编程中特别有用。
  4. 分离构建过程:将复杂对象的构建过程与其表示分离,同样的构建过程可以创建不同的表示。
  5. 控制构建步骤:可以更好地控制构建步骤,例如可以添加一些验证逻辑。

构建者模式特别适用于创建复杂对象,尤其是当对象有多个可选参数或构建步骤时。它可以大大提高代码的可读性、可维护性和灵活性。


http://www.ppmy.cn/server/129185.html

相关文章

奇异值分解SVD

文章目录 奇异值是什么?1 奇异值的定义2 奇异值的性质3 特征值与奇异值的关系4 奇异值的重要性 奇异值分解 奇异值是什么? 1 奇异值的定义 对于任意一个 m n m \times n mn 的矩阵 A A A,存在三个矩阵 U U U, V V V和 Σ \Si…

OpenCV高级图形用户界面(3)关闭由 OpenCV 创建的指定窗口函数destroyWindow()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 销毁指定的窗口。 该函数 destroyWindow 销毁具有给定名称的窗口。 函数原型 void cv::destroyWindow (const String & winname ) 参数 …

基于Springboot+Vue的公寓出租系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

【智能算法应用】人工水母搜索算法求解二维路径规划问题

摘要 本文应用人工水母搜索算法(Jellyfish Search, JFS)求解二维空间中的路径规划问题。水母搜索算法是一种新型的智能优化算法,灵感来源于水母的群体运动行为,通过模仿水母的觅食、漂浮等行为,实现全局最优路径的搜索…

成功解决STM32-No ST-LINK detected问题!

在使用STM32开发板进行编程时,我们可能会遇到“No ST-LINK Detected”的问题,这通常意味着开发环境无法识别或连接到ST-LINK调试器。以下是一些可能的原因和相应的解决方法。 一、原因分析 接线问题:可能是ST-LINK与STM32开发板之间的连接不…

国庆练习(Day24)

作业一 数组练习 选择题 1.1、若有定义语句:int a[3][6]; ,按在内存中的存放顺序,a 数组的第10个元素是 a[0][4] B) a[1][3] C)a[0][3] D)a[1][4] 解析: 从 a[0][0] 开始…

【leetcode】238.除自身以外数组的乘积

由于该题不能使用除法,所以参考题解写一个左右乘积列表的方法 创建两个新的数组pef,suf 一个用于记录从左到右的乘积(类似于动态规划的思想)pef 另一个记录从右到左的乘积 bsuf(注意suf是从右到左进行累乘) 而pef的最左…

Spring Boot实现新闻个性化推荐

1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…