❓直接使用构造函数或者配合 set 方法就能创建对象,为什么还需要建造者模式来创建呢?
❓建造者模式和工厂模式都可以创建对象,那它们两个的区别在哪里呢?
一、为什么需要建造者模式?
❓我们通常使用 new 关键字调用类的构造函数来创建对象,那么什么情况下不适用这种方式而采用建造者模式来创建对象呢?
📚 1.1 需求:定义一个资源池配置类
需要定义一个资源池配置类 ResourcePoolConfig -资源池,你可以简单理解为线程池、连接池、对象池等。其有几个成员变量,也就是可配置项
❓ResourcePoolConfig 构造函数中只有 4 个参数,但如果可配置项变成了 8 个、10 个怎么办?
⚠️构造函数的参数列表会变得很长,代码在可读性和易用性上都会变差。在使用构造函数的时候容易搞错各参数的顺序,传递进错误的参数值,导致非常隐蔽的 bug。
解决这个问题的办法就是用 set() 函数来给成员变量赋值,以替代冗长的构造函数。
必填项在构造方法中设置,非必填使用set方法来设置
📚1.2 资源池配置类新需求
1 必填的配置项有很多
2 配置项之间有一定的依赖关系,比如,maxIdle 和 minIdle 要小于等于 maxTotal
3 ResourcePoolConfig 类对象是不可变对象,即对象在创建好之后,就不能再修改内部的属性值
❓ 如何实现上面的新需求?
🐴这时候建造者模式就派上用场了:
1 先创建Builder对象,并且通过set方法设置Builder对象的变量值。
2 然后再调用Builder对象的build方法创建 ResourcePoolConfig 对象,而校验逻辑就放在build方法中,校验通过之后才会调用ResourcePoolConfig的构造方法创建对象,构造方法的参数就是Builder对象(这样在构造方法中就可以获取Builder对象的属性值来初始化ResourcePoolConfig了)。
3 ResourcePoolConfig构造函数改为 private 私有权限,并不提供set方法
🐴总结:先准备,再校验,校验好后创建对象。
📚1.3 长方形需求
比如我们定义了一个长方形类,如果不使用建造者模式,采用先创建后 set 的方式,那就会可能设置宽大于长,使得整个对象处于无效状态。
1.4 建造者模式的缺点
建造者类和被建造类中的成员变量重复,如果不关心对象是否处于无效状态,也不在意对象是否可变,就可以不使用建造者模式,直接暴露set方法来设置成员变量的值。