Java链式编程与Builder(建造者)设计模式

news2024/10/5 13:06:41

一、链式编程

1.1.释义 

        链式编程,也叫级联式编程,调用对象的函数时返回一个this对象指向对象本身,达到链式效果,可以级联调用。 

1.2.特点 

        可以通过一个方法调用多个方法,将多个方法调用链接起来,形成一条“链式”,从而提高代码的可读性。 

 1.2.原理

        链式编程的原理是返回一个this对象,也就是返回对象本身,从而达到链式效果。 

1.3.优点 

        编程性强、代码简洁 、可读性强。

1.4.使用条件 

        方法返回当前对象,即返回this;或方法支持链式调用,即返回调用该方法的对象。 

1.4.1.使用示例 

import lombok.Data;

/**
 * 要实现链式编程,我们需要让setParam1()和setParam2()都返回this。
 * 当手写set方法时,无需 @Data注解
 * 在此仅为了使用 @Data的toString()
 */
@Data
public class Sample {

    private String param1;
    private String param2;
    private String param3;

    public Sample setParam1(String param1) {
        this.param1 = param1;
        return this;
    }
    public Sample setParam2(String param2) {
        this.param2 = param2;
        return this;
    }
    public Sample setParam3(String param3) {
        this.param3 = param3;
        return this;
    }
}

 1.4.2.示例输出

二、String链式示例

2.1.源码 

         例如可以将某对象toString()转化为String后,或将String对象valueOf()赋值后,进行concat()拼接、replace()替换、substring()截取。符合的方法很多,大多数都能组装起来,使之符合链式编程。

三、StringBuffer和StringBuilder链式示例

3.1.源码 

3.2.使用示例 

        同时,Collection接口下的List的stream流,也是使用的链式编程,这里不做介绍。 

四、@Accessors注解开启链式编程 

4.1.源码 

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Accessors {
	/**
	 * If true, accessors will be named after the field and not include a {@code get} or {@code set}
	 * prefix. If true and {@code chain} is omitted, {@code chain} defaults to {@code true}.
	 * <strong>default: false</strong>
	 * 
	 * @return Whether or not to make fluent methods (named {@code fieldName()}, not for example {@code setFieldName}).
	 */
	boolean fluent() default false;
	
	/**
	 * If true, setters return {@code this} instead of {@code void}.
     * 如果是true,setters方法返回{this} 而不是{void}
     * 
	 * <strong>default: false</strong>, unless {@code fluent=true}, then <strong>default: true</strong>
	 * 
	 * @return Whether or not setters should return themselves (chaining) or {@code void} (no chaining).
	 */
	boolean chain() default false;
	
	/**
	 * If present, only fields with any of the stated prefixes are given the getter/setter treatment.
	 * Note that a prefix only counts if the next character is NOT a lowercase character or the last
	 * letter of the prefix is not a letter (for instance an underscore). If multiple fields
	 * all turn into the same name when the prefix is stripped, an error will be generated.
	 * 
	 * @return If you are in the habit of prefixing your fields (for example, you name them {@code fFieldName}, specify such prefixes here).
	 */
	String[] prefix() default {};
}

 4.2.注解使用

@Data
@Accessors(chain = true)
public class Sample {

    private String param1;
    private String param2;
    private String param3;

}

        上述代码是对1.4.1中的示例代码进行的简化,可以看出,当使用注解时,不用自己再设计具体的链式实现,注解会开启链式操作。这个注解常用在Spring中的实体类上。 

        同时,使用@Accessors(fluent = true)时,省略给对象赋值和取值时候得set、get前缀,可以直接用对象点出来元素,不用set。 

 4.3.测试

 五、使用Builder模式实现Java链式编程

        Builder模式是一种对象创建模式,允许我们创建一个对象,并设置其属性值。示例的Builder模式实现如下所示:        

public class Sample {

    private String name;
    private String gender;
    private String age;

    private Sample(){}
    public static SampleBuilder builder() {
        return new SampleBuilder();
    }

    public static class SampleBuilder {

        private Sample sample = new Sample();

        public SampleBuilder setName(String name) {
            sample.name = name;
            return this;
        }

        public SampleBuilder setGender(String gender) {
            sample.gender = gender;
            return this;
        }
        public SampleBuilder setAge(String age) {
            sample.age = age;
            return this;
        }

        public Sample build() {
            return sample;
        }
    }
}

        在上面的代码示例中,我们首先创建了一个Sample类。为了实现Builder模式,我们还创建了一个SampleBuilder类。SampleBuilder类中有两个with方法,分别用于设置name属性、gender属性和age属性。它们都返回SampleBuilder对象,这样就可以实现链式调用。在参数设置完成后,我们通过build方法创建Sample对象。使用Builder模式进行链式编程的示例如下:

         在上面的示例中,我们通过Sample.builder()创建了SampleBuilder对象,并使用其中的set方法设置参数。在设置完成后,我们通过build方法创建了Sample对象。

        上面这就是一个最简单的builder链式编程,简单在于,能成链能赋值,仅此而已。但如果需要取值,需要对参数校验,这个类就不够用了,需要补充更多的规定,这就抛砖引玉的引出了Java重要设计模式之一的建造者模式。

六、Builder(建造者)设计模式 

6.1.实用范围

        当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

        当构造过程必须允许被构造的对象有不同表示时。

 6.2.角色

        在这样的设计模式中,有以下几个角色:

        1 builder:为创建一个产品对象的各个部件指定抽象接口。

        2 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。

        3 Director:构造一个使用Builder接口的对象。

        4 Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

 6.3.Builder 模式创建步骤

        1)在类中,创建一个静态内部类,包含外部类的全部属性;

        2)在内部类中,为每一个属性进行赋值;

        3)内部类中创建 build 方法,返回外部类对象

        4)在外部类中创建静态 builder方法,返回内部类对象

6.4.残次品示例 

public class Sample {

    //Sample 类的属性都是不可变的。所有的属性都添加了final修饰符,在构造方法中设置了值。
    private final String name;
    private final String gender;
    private final Double age;
    //对外只提供getters方法。
    public String getName() {
        return name;
    }
    public String getGender() {
        return gender;
    }
    public Double getAge() {
        return age;
    }
    //Sample 类的构造方法是私有的。也就是说调用者不能直接创建User对象。
    private Sample(SampleBuilder builder){
        this.name = builder.name;
        this.gender = builder.gender;
        this.age = builder.age;
    }
    public static class SampleBuilder {
        private String name;
        private String gender;
        private Double age;
        public SampleBuilder SampleBuilder(){
            return new SampleBuilder();
        }

        public SampleBuilder setName(String name) {
            this.name = name;
            return this;
        }

        public SampleBuilder setGender(String gender) {
            this.gender = gender;
            return this;
        }
        public SampleBuilder setAge(Double age) {
            this.age = age;
            return this;
        }

        public Sample build() {
            //添加参数校验
            Sample sample = new Sample(this);
            if (sample.getAge() < 0 || sample.getAge() > 125){
                throw new IllegalStateException("Age out of range:" + sample.getAge());
            }
            if (!("男".equals(sample.getGender()) || "女".equals(sample.getGender()))){
                throw new IllegalStateException("Error Gender Input:" + sample.getGender());
            }
            return sample;
        }
    }
}

         可以看到,基本链式编程形成,同时参数也会进行校验,符合要求。但之所以叫残次品,是因为这只是build链式开发,但说设计模式,明显“德不配位”。

weiwan,daixu 

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

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

相关文章

Mysql数据NULL避坑指南

NULL空值是mysql中一种特殊的数据值&#xff08;即"缺少的未知值"&#xff09;,NULL和字符串空值不是一回事&#xff0c;处理NULL与其他值不同&#xff0c;下面具体阐述相关差异&#xff1a; 一、NULL运算符 1、普通数据使用 > 、 < 、即可做常用的逻辑运算如…

Linux随机生成数

简介 在某些情况下&#xff0c;我们需要随机产生一个数来在一些场景中使用&#xff0c;例如验证码、ssh反向代理随机数的产生&#xff0c;又或者在一些shell脚本设计中需要用到随机数&#xff0c;下面以随机产生一个30000-40000之间的随机数为例。 使用shuf shuf 命令在一些 Li…

【FFMPEG】AVFilter使用流程

流程图 核心类 AVFilterGraph ⽤于统合这整个滤波过程的结构体 AVFilter 滤波器&#xff0c;滤波器的实现是通过AVFilter以及位于其下的结构体/函数来维护的 AVFilterContext ⼀个滤波器实例&#xff0c;即使是同⼀个滤波器&#xff0c;但是在进⾏实际的滤波时&#xff0c;也…

基于单片机水质检测系统的设计与实现

功能介绍 以STM32单片机作为主控系统&#xff1b;液晶显示当前参数&#xff1b;PH模块采集当前水质PH酸碱度&#xff1b;DS18B20温度传感器采集当前水体温度&#xff1b;TDS传感器采集当前水体TDS值&#xff1b;浊度传感器采集当前水体浑浊度&#xff1b;按键设置PH、温度、TDS…

基于vscode连接到远程服务中debug

本文章主要讲解以下两点的任务 1.在windows的vscode中去debug 本机子系统wsl2中运行的docker容器 该篇文件参考知乎上这篇文章 vscode远程连接到本机 wsl2子系统 中正在运行的 docker容器&#xff0c;该docker中有一个flask实例&#xff0c;通过vscode远程debug它 1.1安装v…

基于matlab配置单目鱼眼摄像头(附源码)

一、前言 此示例演示如何将鱼眼相机模型转换为针孔模型&#xff0c;并构建相应的单目相机传感器仿真。 要模拟安装在车辆中的单目摄像头传感器&#xff0c;请执行以下步骤&#xff1a; 通过使用棋盘格校准相机来估计固有的相机参数。内在参数描述了鱼眼镜头相机本身的特性。 …

抖音seo矩阵系统源码部署开发-可二开(二)

抖音seo短视频剧组嗯系统是以人工智能技术&#xff0c;通过多个短视频平台&#xff0c;多个短视频账号为核心&#xff0c;视频自动生成、自动发布智能优化&#xff0c;以达到矩阵营销的目的&#xff0c;从根本上解决短视频曝光难和获客少等难题&#xff0c;从而快速增加商家的运…

基于matlab使用卷积神经网络对晶圆图上的八种制造缺陷进行分类(附源码)

一、前言 此示例展示了如何使用简单的卷积神经网络 &#xff08;CNN&#xff09; 对晶圆图上的八种制造缺陷进行分类。 晶圆是半导体材料&#xff08;通常是硅&#xff09;的薄盘&#xff0c;用作集成电路的基础。每个晶圆产生几个单独的电路&#xff08;IC&#xff09;&…

XXX汽车ERP系统供应商索赔业务上线,助力业财数据快速闭环(投稿数据化月报四)

供应商三包索赔款项源起QMS质量系统&#xff0c;联动金税系统完成发票开具&#xff0c;最终在SAP系统中创建完成财务凭证。该流程上线前为手工操作&#xff0c;费时费力且效率低下容易出错。针对该业务现状&#xff0c;SAP与QMS业务顾问及开发团队组成开发小组&#xff0c;导入…

Java性能权威指南-总结26

Java性能权威指南-总结26 数据库性能的最佳实践异常日志 数据库性能的最佳实践 异常 Java的异常处理一直有代价高昂的坏名声。其代价确实比处理正常的控制流高一些&#xff0c;不过在大多数情况下&#xff0c;这种代价并不值得浪费精力去绕过。另一方面&#xff0c;因为异常处…

添加 zabbix 客户端主机 自定义监控内容 自动发现与注册(得不到假装不想要)

文章目录 一、添加zabbix客户端主机2.关闭防火墙和修改主机名 二、自定义监控内容1.需求&#xff1a;限制登录人数不超过 3 个&#xff0c;超过 3 个就发出报警信息在客户端创建自定义 key在 Web 页面创建自定义监控项模板 三、zabbix 自动发现与自动注册zabbix 自动发现&#…

HCIE-datacom | 网络准入控制

一、前言 之前提供网络技术咨询服务时&#xff0c;有一位实习生同学向我咨询了有关网络准入的相关情景&#xff0c;在这里我结合华为HCIE-datacom中“网络准入控制”这一节等相关资料&#xff0c;对网络准入技术进行一下简单的理论性说明&#xff0c;与资料的讲解思路相同&…

基于matlab使用AprilTag标记进行相机校准(附源码)

一、前言 AprilTags被广泛用作物体检测、定位应用的视觉标记&#xff0c;并作为相机校准的目标。AprilTags类似于QR码&#xff0c;但旨在编码更少的数据&#xff0c;因此可以更快地解码&#xff0c;这对于实时机器人应用程序非常有用。使用 AprilTags 作为校准模式的优点包括更…

Docker学习笔记21

案例三&#xff1a;使用容器运行一个wordpress应用&#xff1a; 语言开发环境&#xff08;PHP&#xff09; 数据库 第一步&#xff1a;创建一个工程目录&#xff1a; mkdir wordpress cd wordpress 第二步&#xff1a;创建一个docker-compose.yaml文件&#xff1a; [rootnode…

Mybatis进阶(2)——为什么用mybatis? 多表查询解决 延迟加载 mybatis缓存 【未完待续】

目录 引出一、为啥用mybatis&#xff1f;二、多表查询之一对多【待续】1.一对多的情况方案一&#xff1a;采用多表联查的方式&#xff08;1&#xff09;resultMap&#xff08;2&#xff09;查询的java接口和xml的SQL语句&#xff08;3&#xff09;对应关系分析&#xff08;4&am…

使用docker搭建minio分布式对象存储系统

使用docker搭建minio分布式对象存储系统 这里我简单的和大家介绍一下什么是minio &#xff1f; 附上Minio官网链接&#xff1a;https://minio.org.cn/ MinIO是一种开源的对象存储服务器&#xff0c;通过使用标准的HTTP/REST API来访问和管理数据。它采用分布式架构&#xff0c…

【SAP UI5 控件学习】DAY02 Input组PartII

1. CheckBox控件 1.1 最普通的CheckBox <CheckBox text"Option a" selected"true" />如果需要设置选中状态&#xff0c;需要设置selected属性为true 1.2 部分选中CheckBox <CheckBox text"Option partially selected" selected"t…

【ElasticSearch】DSL查询语法

文章目录 1、DSL查询分类2、DSL基本语法3、全文检索查询4、精确查询5、地理查询6、复合查询--相关性打分算法7、复合查询之Function Score Query8、复合查询之BooleanQuery 1、DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;…

【ARM Coresight 系列文章 2 - ARM Coresight 介绍】

文章目录 1.1 ARM Coresight 介绍1.1.1 ARM Coresight 发展历史 1.2 ARM Coresight 框架介绍1.1.1 Trace 通路1.1.3 Debug 通路1.1.4 Trigger 通路 1.1 ARM Coresight 介绍 ARM Coresight是ARM公司提供的一种调试和跟踪技术&#xff0c;用于ARM处理器的调试和性能分析。它通过…

Java中规模软件开发实训——简单的文本编辑器(代码注释详解)

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;html css js&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;在现代社会中…