Builder构建者模式,将复杂对象的创建过程与其表示分离,活学活用才是王道

“, i3=” + i3 +

‘}’;

}

public static class Builder {

private String s1;

private String s2;

private String s3;

private Integer i1;

private Integer i2;

private Integer i3;

public static Builder create(String s1) {

return new Builder(s1);

}

private Builder(String s1) {

this.s1 = s1;

}

public Builder setS1(String s1) {

this.s1 = s1;

return this;

}

public Builder setS2(String s2) {

this.s2 = s2;

return this;

}

public Builder setS3(String s3) {

this.s3 = s3;

return this;

}

public Builder setI1(Integer i1) {

this.i1 = i1;

return this;

}

public Builder setI2(Integer i2) {

this.i2 = i2;

return this;

}

public Builder setI3(Integer i3) {

this.i3 = i3;

return this;

}

public Product build() {

// 1. s1 必传

if (s1 == null || s2 == “”) {

throw new IllegalArgumentException(“s1必传,不可为空!”);

}

// 2. s2 s3 非必填,但是具有依赖关系,即s2传了,s3也必须传

if (s2 != null && s2 != “”) {

if (s3 == null || s3 == “”) {

throw new IllegalArgumentException(“s2与s3具有依赖关系!”);

}

}

// 3. i1 不传或者 i1 <= 0 则默认为 1

if (i1 == null || i1 <= 0) {

i1 = 1;

}

// 4. i2非必传 但是需要校验有效性,不能小于0

if (i2 != null && i2 < 0) {

throw new IllegalArgumentException(“i2 不能小于0”);

}

Product product = new Product(this);

return product;

}

}

}

public class Test {

public static void main(String[] args) {

Product product = Product.Builder.create(“1”)

.setS2(“2”)

.setS3(“3”)

.setI1(0)

.setI2(2)

.setI3(3)

.build();

System.out.println(product.toString());

}

}

// Product{s1=‘1’, s2=‘2’, s3=‘3’, i1=1, i2=2, i3=3}

注意:

  • Builder可以是内部类,也可以是外部类,视情况而定,一般情况是作为产品类的内部类,这样产品类多了,不至于多出很多Builder类,让代码结构变得复杂。

  • Builder和产品类中代码重复,产品类的属性需要复制一份到Builder,并且要保持同步更新。

  • Builderset方法需要返回Builder本身,达到链式调用的效果。

  • Builderbuild()方法中实例化产品类,并且做一些必要的参数校验,非必填的参数校验也可以放到set里。

  • Product产品类的构造函数设置成private的,并且没有对外提供set方法,主要是为了创建产品类只能通过Builder,并且创建出来的对象是不可修改的。

  • Product的构造函数的参数为Builder,这样为了方便将值复制给Product,也可以不用这样做。

  • Product.Builder对外提供了一个静态方法create,这个方法可有可无,是将Builder的创建隔离,同时一些必填参数也可以通过Builder的构造函数传入。

2、构建者模式的优缺点

(1)优点:隔离了复杂对象的创建细节,方便客户端调用,减少了不必要的bug。

(2)缺点:代码重复,有一定的维护成本。

总结一句就是,方便他人,麻烦自己

3、构建者模式与工厂模式的区别

(1)工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象,一般这个创建过程也比较简单,如果复杂的话,可以工厂模式和构建者模式结合。

(2)构建者模式是用来创建一种类型的复杂对象,通过设置不同的可选参数,“定制化”创建不同的对象

三、构建者模式在源码架构中的体现


1、JDK的StringBuilder

JDK中StringBuilder其实就是用了构建者模式,append拼接字符串,最后toString生成一个String对象。

StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append(“1”).append(“2”).toString();

2、Tomcat中ServerEndpointConfig的构建

ServerEndpointConfig.Builder

3、MyBatis中SqlSessionFactoryBuilder

SqlSessionFactoryBuilder中只有多个build方法,并且参数直接从build中传入,这就是灵活应用,必填项有多种情况,那就对外提供多个不同参数列表的build,外界一看build方法就知道怎么调用。

SqlSessionFactoryBuilder

4、Spring中也大量用到构建者模式

(1)比如org.springframework.beans.factory.support.BeanDefinitionBuilderBeanDefinition中存在多个属性,但是Spring没有在BeanDefinitionBuilder再复制一遍,而是直接new一个BeanDefinitionBeanDefinitionBuilder,后面设置属性时,也是直接设置给了BeanDefinition对象,这样做的好处是减少重复代码,灵活使用构建者模式。

BeanDefinitionBuilder

(2)再比如org.springframework.messaging.support.MessageBuilder,这个构建者模式就用的比较中规中矩了:

MessageBuilder

MessageBuilder

四、要点回顾


构建者模式本身很简单,难的是活学活用,认识其本质,为什么那么设计?解决了什么问题?才能避免生搬硬套。

  1. 构建者模式,将复杂对象的创建过程与其表示分离,通过设置不同的可选参数,“定制化”创建不同的对象表示。

  2. 构建者模式主要解决了传统创建复杂对象(创建的过程较复杂),构造函数参数列表过长,无法做复杂校验等问题。

  3. 看了开源框架中对构建者模式的应用,并没有中规中矩,学到两点:如果必填参数的情况比较多,且每种情况参数个数较少,可以直接重载多个build方法,这样外界调用也非常直观;如果类对象属性较多,可以不必要在Builder里再把属性复制一份,而是在创建Builder同时创建产品对象,后面set值直接set给产品对象,build时再做一些参数校验。

  4. 对于一些中间对象,比如数据库映射,某个方法因参数过多封装成一个类,后面并不关心这个对象的无状态(可以随意set),即使属性较多,也没必要使用构建者模式。

参考:

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
fZ4AuISY-1715618842838)]

[外链图片转存中…(img-qcKBzDIT-1715618842838)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值