重读Java设计模式: 深入探讨建造者模式,构建复杂对象的优雅解决方案

news/2024/6/20 20:17:45/文章来源:https://blog.csdn.net/MarkusZhang/article/details/137194125

引言

在软件开发中,有时需要构建具有复杂结构的对象,如果直接使用构造函数或者 setter 方法逐个设置对象的属性,会导致代码变得冗长、难以维护,并且容易出错。为了解决这个问题,我们可以使用建造者模式。

一、建造者模式概述

建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式常用于构建具有复杂结构的对象,例如包含多个部件的对象,或者对象的构建过程需要进行多个步骤。

二、建造者模式的结构

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

  • 产品(Product):要构建的复杂对象,它由多个部件组成。
  • 抽象建造者(Builder):定义了构建产品的抽象方法,具体建造者类将实现这些方法来构建具体的产品。
  • 具体建造者(Concrete Builder):实现了抽象建造者定义的方法,负责构建产品的各个部件,并返回构建后的产品。
  • 指挥者(Director):负责使用建造者构建产品的对象,它通常不了解具体的构建过程,只负责按照指定的步骤调用建造者的方法来构建产品。

三、建造者模式的优点

  • 分步构建:将构建过程分步进行,每一步都由具体建造者负责,可以更加精细地控制构建过程。
  • 隔离复杂性:将构建过程与产品的表示分离,使得构建过程的变化不会影响产品的表示,从而提高了系统的灵活性和可维护性。
  • 复用性:可以使用相同的构建过程来构建不同的产品,提高了代码的复用性。
  • 逐步完善:可以逐步完善构建过程,根据需求的变化灵活地调整构建过程。

四、建造者模式的应用场景

  • 需要构建的产品具有复杂的内部结构,包含多个部件。
  • 需要构建的产品的构建过程需要进行多个步骤,并且每个步骤的实现方式可能不同。
  • 需要构建的产品的属性之间存在一定的约束关系,需要按照一定的顺序来构建产品。

五、建造者模式的示例代码

我们先来看下相关 UML 图

image-20240331101403448

  • 产品角色
package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public class Car {private Wheel wheel;private SteeringWheel steeringWheel;public Wheel getWheel() {return wheel;}public void setWheel(Wheel wheel) {this.wheel = wheel;}public SteeringWheel getSteeringWheel() {return steeringWheel;}public void setSteeringWheel(SteeringWheel steeringWheel) {this.steeringWheel = steeringWheel;}@Overridepublic String toString() {return "Car{" +"wheel=" + wheel +", steeringWheel=" + steeringWheel +'}';}
}package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public interface SteeringWheel {String steeringWheel();
}package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public class XiaomiSteeringWheel implements SteeringWheel {@Overridepublic String steeringWheel() {return "小米轮毂";}
}package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public interface Wheel {String wheelType();
}package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public class XiaomiWheel implements Wheel{@Overridepublic String wheelType() {return "小米方向盘";}
}
  • 抽象构建者
package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public abstract class CarBuilder {protected Car car = new Car();public abstract CarBuilder buildWheel(Wheel wheel);public abstract CarBuilder buildSteeringWheel(SteeringWheel steeringWheel);public Car builder() {return car;}
}
  • 具体构建者
package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public class CommonCarBuilder extends CarBuilder {@Overridepublic CarBuilder buildWheel(Wheel wheel) {this.car.setWheel(wheel);return this;}@Overridepublic CarBuilder buildSteeringWheel(SteeringWheel steeringWheel) {this.car.setSteeringWheel(steeringWheel);return this;}
}
  • 指挥官
package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public interface Director<T> {T construct();
}package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description: 小米制造商*/
public class XiaoMiDirector implements Director<Car> {private CarBuilder carBuilder;public XiaoMiDirector(CarBuilder carBuilder) {this.carBuilder = carBuilder;}@Overridepublic Car construct() {carBuilder.buildWheel(new XiaomiWheel());carBuilder.buildSteeringWheel(new XiaomiSteeringWheel());return carBuilder.builder();}
}
  • 客户端
package com.markus.desgin.mode.creational.builder;/*** @Author: zhangchenglong06* @Date: 2024/3/7* @Description:*/
public class Client {public static void main(String[] args) {CarBuilder carBuilder = new CommonCarBuilder();Director<Car> director = new XiaoMiDirector(carBuilder);Car car = director.construct();System.out.println(car);}
}

六、建造者模式在 Spring 中的应用

在Spring框架中,有几个组件使用了建造者模式的思想来构建复杂对象,其中包括:

  1. RestTemplateBuilderRestTemplateBuilder是用于构建RestTemplate实例的建造者。RestTemplate是Spring提供的用于访问Restful服务的工具类,它支持各种HTTP请求方法和数据交换格式,如JSON和XML。RestTemplateBuilder提供了一系列方法来配置RestTemplate的各种属性,例如连接超时、读取超时、拦截器等,使得构建RestTemplate实例更加灵活和便捷。
  2. WebMvcConfigurerWebMvcConfigurer是Spring MVC框架中的一个接口,用于配置Web MVC的行为。在Spring Boot应用程序中,通常会创建一个实现了WebMvcConfigurer接口的配置类来自定义Web MVC的行为。通过实现WebMvcConfigurer接口,可以通过覆盖其中的方法来配置拦截器、消息转换器、视图解析器等各种组件,从而实现对Spring MVC框架的定制化。这种灵活性和可定制性正是建造者模式的优势之一。
  3. SqlSessionFactoryBean: 在Spring中使用MyBatis进行持久化操作时,通常会配置一个SqlSessionFactoryBean实例来创建SqlSessionFactory对象。SqlSessionFactory是MyBatis框架中的核心接口,用于创建SqlSession对象,通过SqlSession对象可以执行SQL语句并与数据库进行交互。SqlSessionFactoryBean提供了一系列方法来配置MyBatis的各种属性,例如数据源、类型别名、Mapper扫描等,使得创建SqlSessionFactory实例更加灵活和可配置。

这些组件在Spring框架中使用建造者模式的思想,通过提供一系列的配置方法来构建复杂的对象实例,使得对象的创建过程更加灵活和可定制。

七、设计模式百宝箱

在本节,我们开始填充我们的百宝箱:

  • 面向对象基础
    • 抽象
    • 封装
    • 多态
    • 继承
  • 面向对象原则
    • 依赖抽象,不要依赖具体类
    • 针对接口编程,不针对具体实现编程
    • 类应该对扩展开放,对修改关闭
    • 为交互对象之间的松耦合设计而努力
  • 面向对象设计模式
    • 简单工厂模式:定义了一个创建对象的接口,将创建对象的内容从客户端抽离出来
    • 抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
    • 原型模式:通过复制现有对象来创建新对象,提高代码效率和可维护性
    • 建造者模式:将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示

八、总结

建造者模式是一种创建型设计模式,通过将构建过程与产品的表示分离,使得同样的构建过程可以创建不同的表示。本文介绍了建造者模式的概念、结构、优点、应用场景,并提供了示例代码进行说明。建造者模式可以有效地解决构建复杂对象时的代码冗长、难以维护的问题,是一种值得推荐的设计模式。

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

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

相关文章

HarmonyOS实战开发-slider组件的使用

介绍 本篇Codelab主要介绍slider滑动条组件的使用。如图所示拖动对应滑动条调节风车的旋转速度以及缩放比例。 相关概念 slider组件&#xff1a;滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。 环境搭建 软件要求 DevEco Stu…

基于YOLOV5+Pyqt5农作物叶片病害检测系统

1、引言 农作物病害的精准检测与识别是推动农业生产智能化与现代化发展的重要举措。随着计算机视觉技术的发展&#xff0c;深度学习方法已得到快速应用&#xff0c;利用卷积神经网络进行农作物病害检测与识别成为近年来研究的热点。基于传统农作物病害识别方法&#xff0c;分析…

EXCEL VBA将word里面的指定的关键词替换掉后并标记红色字体

EXCEL VBA将word里面的指定的关键词替换掉后并标记红色字体 Sub 开关() Call 新建副本 Call ReplaceAndHighlightInFolder End Sub Sub 新建副本()fpath ThisWorkbook.Path & "\"Dim MyFile As ObjectSet MyFile CreateObject("Scripting.FileSystemObjec…

MySQL数据库(数据库连接池)

文章目录 1.批处理应用1.基本介绍2.批处理演示1.创建测试表2.修改url3.编写java代码 3.批处理源码分析 2.数据库连接池1.传统连接弊端分析2.数据库连接池基本介绍1.概念介绍2.数据库连接池示意图3.数据库连接池种类 3.C3P0连接池1.环境配置1.导入jar包2.将整个lib添加到项目中3…

商业分析师BA与数据分析有什么关系?

文章主题:BA工作与数据分析 分享嘉宾&#xff1a;丛珊 职业&#xff1a;某事业单位BA分析师 在实际工作中&#xff0c;需求分析工作可以有多种分类方法&#xff0c;对于大型、集成型信息系统的需求分析&#xff0c;通常可以区分为业务需求、功能需求、数据需求、性能需求与安…

在java开发中平方怎么表示?平方表示的方法有哪几种?

在java开发中平方怎么表示&#xff1f;平方表示的方法有哪几种&#xff1f; 在我们计算一个数的几次方的时候。我们按照课堂中老师的教法就是在一个数的右上角写上一个小小的数字用来表示一个数的几次方&#xff0c;那么大家知道“在java开发中平方怎么表示吗&#xff1f;“和…

【区块链 链外交易】SoK Off The Chain Transactions

SoK Off The Chain Transactions 摘要 本文对区块链进行了简单介绍,分析目前区块链的缺点——交易吞吐量和速度慢的原因,在此基础上引出解决此问题的方法,也是本轮将要论述的主题——链外交易。之后介绍了链外交易的基本概念和结构,并对两种类型的链外交易:通道和信任链…

在线版的超级马里奥 Super Mario HTML5

原本是在csdn资源找个代码学习的&#xff0c;无奈下载了几份都是垃圾代码(下载了几份都是) 废话不多说&#xff0c;直接上干活。代码、音效、图片、样式都包含 <!doctype html> <html> <head> <meta charsetutf-8 /> <title>Super Mario HTML5 …

VScode-配置文件

导入配置文件 ShiftCtrlp 输入&#xff1a; import 选择文件 点击确认 导出配置文件 设置选择导出 确认导出 保存为本地文件 保存文件

Uibot6.0 (RPA财务机器人师资培训第6天 )发票验真机器人案例实战

类似于小北的这篇博客&#xff1a;Uibot (RPA设计软件&#xff09;Mage AI智能识别&#xff08;发票识别&#xff09;———课前材料五_uibot 添加mageai-CSDN博客https://blog.csdn.net/Zhiyilang/article/details/135591297?spm1001.2014.3001.5501训练网站&#xff1a;泓江…

前端学习<二>CSS基础——13-CSS3属性:Flex布局图文详解

前言 CSS3中的 flex 属性&#xff0c;在布局方面做了非常大的改进&#xff0c;使得我们对多个元素之间的布局排列变得十分灵活&#xff0c;适应性非常强。其强大的伸缩性和自适应性&#xff0c;在网页开中可以发挥极大的作用。 flex 初体验 我们先来看看下面这个最简单的布局…

什么是CSS?

一.CSS&#xff08;层叠样式表&#xff09;&#xff1a;是一种用于描述网页内容任何呈现的样式的语言&#xff0c;它和html&#xff08;超文本标记语言&#xff09;一起用于创建网页和Wed应用程序。 W3C标准&#xff1a;网页主要由三部分组成 结构&#xff1a;html 表现&#x…

B+树:高效管理大规模数据的关键工具

引言 数据库技术已经成为现代信息社会的重要支柱&#xff0c;无论是互联网巨头、金融机构、医疗系统还是智能设备&#xff0c;都离不开数据库的支持。数据库的性能和效率直接关系到这些系统的稳定性和用户体验&#xff0c;而数据库存储结构则是决定其性能的核心因素之一 B树作…

论文笔记:基于多粒度信息融合的社交媒体多模态假新闻检测

整理了ICMR2023 Multi-modal Fake News Detection on Social Media via Multi-grained Information Fusion&#xff09;论文的阅读笔记 背景模型实验 背景 在假新闻检测领域&#xff0c;目前的方法主要集中在文本和视觉特征的集成上&#xff0c;但不能有效地利用细粒度和粗粒度…

Java学习笔记(23)

多线程 并发 并行 多线程实现方式 1.继承Thread类 自己创建一个类extends thread类 Start方法开启线程&#xff0c;自动执行重写之后的run方法 2.实现runable接口 自己创建一个类implements runnable Myrun不能直接使用getname方法&#xff0c;因为这个方法是thread类的方法…

C++——异常机制

目录 一&#xff0c;背景 1.1 C语言处理错误的方式 1.2 C异常概念 二&#xff0c;异常的使用 2.1 异常的简单使用 2.2 异常的匹配原则 2.3 异常抛对象 2.4 异常的重新抛出 2.5 异常安全 三&#xff0c;自定义异常体系 四&#xff0c;异常优缺点 4.1 优点 4.2 缺点 …

【Python项目】AI动物识别工具

目录 背景 技术简介 系统简介 界面预览 背景 成像技术在全球科技发展中扮演了关键角色。在科学研究领域&#xff0c;拍摄所得的图像成为了一种不可或缺的研究工具。特别是在生态学与动物学研究中&#xff0c;鉴于地球的广阔地域和多样的气候条件&#xff0c;利用图像技术捕…

推荐一款命令行随机数据生成工具

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 在shigen之前的文章如何用python优雅的生成模拟数据中&#xff0c;采用了faker这…

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记15:PWM输出

系列文章目录 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记01&#xff1a;赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431&#xff08;HAL库开发&#xff09;——CT117E学习笔记02&#xff1a;开发环境安装 嵌入式|蓝桥杯STM32G431&#xff08;…

C++初学者:优雅创建第一个窗口

我想学习C做一些实用的程序&#xff0c;但是我不想在软件界面上花太多的时间&#xff0c;可是每每就是界面影响我的思绪。 今天学习C类的包装知识&#xff0c;终于整出了一个我的界面类&#xff0c;虽然封装水平很弱&#xff0c; 这次就用这个类&#xff0c;写了自己工作上常用…