[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式

前言:
为什么之前写过Golang 版的设计模式,还在重新写Java 版?
答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。
为什么类图要附上uml
因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那么学习者也只能复制一张图片,可复用性较低,附上uml,方便有新理解时,快速出新图。


🔥[设计模式Java实现附plantuml源码]专链

  1. 确保对象的唯一性~单例模式
  2. 集中式工厂的实现~简单工厂模式
  3. 多态工厂的实现——工厂方法模式
  4. 产品族的创建——抽象工厂模式
  5. 对象的克隆~原型模式
  6. 复杂对象的组装与创建——建造者模式

文章目录

    • 复杂对象的组装与创建——建造者模式
      • 代码简单实现
      • 建造者模式总结
        • 建造者模式的主要优点如下:
        • 建造者模式的主要缺点如下:
      • 适用场景


复杂对象的组装与创建——建造者模式

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一种对象创建型模式。建造者模式一步一步地创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
在这里插入图片描述

@startuml

class Product {
	- partA
	- partB
	- partC

}

abstract class Builder {
	+ buildPartA()
	+ buildPartB()
	+ buildPartC()
	+ getResult(): Product
}

class Director {
- builder
+ construct()
}
note left of Director::"construct()"
	builder.buildPartA();
	builder.buildPartB();
	builder.buildPartC()
	return builder.getResult();
end note

Director *-> Builder: 指挥者跟builder属于组合关系

class concreteBuilder extends Builder {
	+ buildPartA()
	+ buildPartB()
	+ buildPartC()
	+ getResult(): Product
}

concreteBuilder .left..> Product : 具体建造者生产对象



@enduml

在建造者模式结构中包含以下4个角色。
(1)Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口。在该接口中一般声明两类方法:一类方法是 buildPartX(),用于创建复杂对象的各个部件;另一类方法是 getResult(),用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
(2)ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确其所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
(3)Product(产品角色):它是被构建的复杂对象,包含多个组成部件。具体建造者创建该产品的内部表示并定义其装配过程。
(4)Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序。指挥者与抽象建造者之间存在关联关系,可以在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。

代码简单实现

package create;

// 使用示例
public class BuilderDemo {
    public static void main(String[] args) {
        Car car = new CarBuilder()
            .setBrand("Toyota")
            .setModel("Camry")
            .setYear(2022)
            .setHorsepower(203)
            .build();

        System.out.println(car);
    }
}

// 产品类
class Car {
    private final String brand;
    private final String model;
    private final int year;
    private final int horsepower;

    public Car(String brand, String model, int year, int horsepower) {
        this.brand = brand;
        this.model = model;
        this.year = year;
        this.horsepower = horsepower;
    }

    // Getters
    // ...

    @Override
    public String toString() {
        return "Car [brand=" + brand + ", model=" + model + ", year=" + year + ", horsepower=" + horsepower + "]";
    }
}

// 建造者类
class CarBuilder {
    private String brand;
    private String model;
    private Integer year;
    private Integer horsepower;

    public CarBuilder setBrand(String brand) {
        this.brand = brand;
        return this;
    }

    public CarBuilder setModel(String model) {
        this.model = model;
        return this;
    }

    public CarBuilder setYear(int year) {
        this.year = year;
        return this;
    }

    public CarBuilder setHorsepower(int horsepower) {
        this.horsepower = horsepower;
        return this;
    }

    public Car build() {
        if (brand == null || model == null || year == null || horsepower == null) {
            throw new RuntimeException("没有完全建造产品");
        }
        return new Car(brand, model, year, horsepower);
    }
}

建造者模式总结

建造者模式的主要优点如下:

(1)在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
(2)每个具体建造者都相对独立,而与其他具体建造者无关。因此,可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合开闭原则。
(3)可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。

建造者模式的主要缺点如下:

(1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似。如果产品之间的差异性很大,例如很多组成部分都不相同,就不适合使用建造者模式,因此其使用范围受到一定的限制。
(2)如果产品的内部结构复杂且多变,可能会需要定义很多具体建造者类来实现这种变化,这就导致系统变得很庞大,增加系统的理解难度和运行成本。

适用场景

在以下情况下可以考虑使用建造者模式:
(1)需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量。
(2)需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3)对象的创建过程独立于创建该对象的类。在建造者模式中通过引入指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
(4)隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

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

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

相关文章

【K8S 云原生】K8S的图形化工具——Rancher

目录 一、rancher概述 1、rancher概念 2、rancher和K8S的区别: 二、实验 1、安装部署 2、给集群添加监控: 3、创建命名空间: 4、创建deployment: 5、创建service: 6、创建ingress: 7、创建hpa 8…

Android 水印效果

Android 水印效果 本文主要介绍下android 中水印的实现效果. 实现的方式有多种,就不一一赘述了, 本文就是通过自定义drawable来实现水印. 不多说,直接上代码吧: import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; i…

【开源】基于JAVA语言的假日旅社管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿评论4.3 查询民宿新闻4.4 新建民宿预订单4.5 查询我的民宿预订单 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的假日旅社…

LeetCode.2859. 计算 K 置位下标对应元素的和

题目 题目链接 分析 这道题的题意很明确。就是求每一个下标的二进制中1的个数为k的下标所对应的元素值之和。 Java 中有 库函数 Integer.bitCount(num),这个函数的返回值就是 num 中 1 的个数。 代码 class Solution {public int sumIndicesWithKSetBits(List…

【C++】stack、queue的使用及模拟实现

目录 一、stack1.1 stack的使用1.2 stack的模拟实现 二、queue2.1 queue的使用2.2 queue的模拟实现 一、stack 1.1 stack的使用 stack是一种容器适配器,它的特点是后进先出,只能在容器的一端进行插入和删除操作。 stack的使用很简单,主要有…

【RT-DETR有效改进】FasterNet一种跑起来的主干网络( 提高FPS和检测效率)

前言 大家好,这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进,内容持续更新,每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本,同时修改内容也支持ResNet32、ResNet101和PP…

Java中的HTTPS通信

在Java中实现HTTPS通信,主要涉及到SSL/TLS协议的使用,用于提供数据传输的安全性。下面我们将深入探讨如何使用Java进行HTTPS通信。 一、基本概念 HTTPS,全称为Hypertext Transfer Protocol Secure,是HTTP的安全版本。它使用SSL/…

代码随想录 Leetcode144/94/145 二叉树的前/中/后序遍历

题目&#xff1a; 前&#xff1a; 中&#xff1a; 后&#xff1a; 代码&#xff08;首刷自解 2024年1月24日&#xff09;&#xff1a; //前序遍历&#xff0c;递归 class Solution { public:void funcOfRecursion(TreeNode* cur, vector<int>& vec) {if (cur null…

使用frp透传软件搭建本地运行的私有邮箱服务器

起因&#xff1a;随着我公司在线应用软件的增多&#xff0c;比如wordpress、 next cloud、SuitCRM 、iFair等&#xff0c;许多场合都要求填写邮箱地址&#xff0c;绑定邮箱。因为不想将过多的数据存储于第三方空间&#xff0c;因此考虑在公司局域网内搭建一个私有的电子邮箱服务…

嵌入式软件工程师如何快速成长

今天和大家分享一下&#xff0c;程序员如何独挡一面这个话题&#xff0c;这是一个很大的话题&#xff0c;我把他分成三部分来谈&#xff1a; 一、需求转换的能力或者叫理解需求的能力&#xff1b; 二、分配时间的能力&#xff1b; 三、开发质量的问题&#xff1b; 我为什么…

全新UI基于Thinkphp的最新自助打印系统/云打印小程序源码/附教程

这是一款全新的基于Thinkphp的最新自助打印系统&#xff0c;最新UI界面设计的云打印小程序源码&#xff0c;带有简单的教程。 源码下载&#xff1a;YISHEN源码网&#xff08;ms3.ishenglu.c&#xff09;om

Java-反射-注解-动态代理

二、反射 翻译成人话就是&#xff1a;反射技术&#xff0c;指的是加载类的字节码到内存&#xff0c;并以编程的方法解刨出类中的各个成分&#xff08;成员变量、方法、构造器等&#xff09;。 反射有啥用呢&#xff1f;其实反射是用来写框架用的&#xff0c;但是现阶段同学们对…

RK3588平台开发系列讲解(视频篇)RKMedia框架

文章目录 一、 RKMedia框架介绍二、 RKMedia框架API三、 视频处理流程四、venc 测试案例沉淀、分享、成长,让自己和他人都能有所收获!😄 📢RKMedia是RK提供的一种多媒体处理方案,可实现音视频捕获、音视频输出、音视频编解码等功能。 一、 RKMedia框架介绍 功能: VI(输…

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测,预测新数据

碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测&#xff0c;预测新数据 目录 碳排放预测 | Matlab实现LSTM多输入单输出未来碳排放预测&#xff0c;预测新数据预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现LSTM长短期记忆神经网络多输入单输出未来…

Sentinel-1 扩展时序注释数据集 (ETAD)的查询和下载

概述 Sentinel-1的扩展计时注释数据集&#xff08;ETAD&#xff09;是ESA&#xff08;DLR作为承包商&#xff09;开发的新辅助产品&#xff0c;为用户提供校正&#xff0c;将Sentinel-1 SLC图像的几何精度提高到厘米级别。该产品包含分析就绪层&#xff0c;用于消除大气路径延…

Linux系统中虚拟文件系统原理与方法

在 Unix 的世界里&#xff0c;有句很经典的话&#xff1a;一切对象皆是文件。这句话的意思是说&#xff0c;可以将 Unix 操作系统中所有的对象都当成文件&#xff0c;然后使用操作文件的接口来操作它们。Linux 作为一个类 Unix 操作系统&#xff0c;也努力实现这个目标。 虚拟文…

三维重建(6)--多视图几何

目录 一、运动恢复问题&#xff08;SfM&#xff09; 二、欧式结构恢复问题 1、概述 2、算法流程 3、本质矩阵分解 4、欧式结构恢复歧义 三、仿射结构恢复问题 1、概述 2、因式分解法 3、仿射结构恢复歧义 四、透视结构恢复问题 1、概述 2、透视结构恢复歧义 3…

【数据结构与算法】之字符串系列-20240125

字符串系列 一、520. 检测大写字母二、面试题 01.01. 判定字符是否唯一三、面试题 01.02. 判定是否互为字符重排四、面试题 01.03. URL化五、面试题 01.04. 回文排列六、面试题 01.09. 字符串轮转 一、520. 检测大写字母 简单 我们定义&#xff0c;在以下情况时&#xff0c;单…

分布式应用程序设计项目管理

1. 项目的定义 项目是一种特定的、新颖的行动&#xff0c;目的是以有条不紊、逐步的方式构建一个尚未存在确切对应物的未来现实。它是对精心制定的需求的回应&#xff0c;旨在满足业主的需要。项目包括一个可能是物理或智力的目标&#xff0c;并且需要使用给定的资源来执行一系…

【SD】sadtalk

下载地址&#xff1a; 123&#xff1a;https://www.123pan.com/s/VzULVv-0OXX.html 提取码:3KhD 百度&#xff1a; https://pan.baidu.com/share/init?surlRB9oTmlbIV0pg1Th-Tdd4Q 提取码: uk87 效果不是很好&#xff0c;适合小图片。推荐&#xff1a;heygen 参考设置&…