构造函数有多个参数时要考虑使用Builder

简介: 假设一个类的构造函数有多个参数时,如果想要创建实例时,很可能就会写出这样的代码:

多参数构造函数:


假设一个类的构造函数有多个参数时,如果想要创建实例时,很可能就会写出这样的代码:


NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);


这个调用通常需要许多你根本不想设置的参数,但却不得不设置,比如第三个传入的0。这种方式是可行的,但如果有很多参数的时候,客户端代码会很难编写,程序员会因为要避免传错参而小心翼翼。


记得之前在公司里面用了其他人封装的日志工具类LogUtil,里面的构造函数就是这样的风格~~,不仅传的参数多,还提供了各种各样不同参数组合的构造函数,最后当然逃不过被重写的命运 : )


JavaBeans模式:


NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);


这种模式下先调用无参构造器创建对象,再调用setter方法来设置每个必要的参数,这样的代码可读性要更高,但却有严重的缺点:


创建对象的过程不是原子的,于是在高并发场景下可能产生不一致的对象

JavaBeans模式无法将类做成不可变的,因为调用了setter方法本身就意味着“可变”了


建造者(Builder)模式:


Mybatis中的SqlSessionFactoryBuilder就是建造者模式的体现,在类的定义里面,builder通常是类的静态成员类,并且调用无参的build方法生成的通常是不可变的对象,使用示例:


NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();

Builder模式十分灵活,可以利用单个builder构建多个对象;builder的参数可以在调用build方法来创建对象期间进行调整,甚至可以填充某些域,比如创建新对象是自动增加序号值。


相关文章
|
1月前
|
搜索推荐
如何在构造函数中为类的实例添加方法?
在实际开发中,要根据具体的场景和需求来选择合适的方式来为类的实例添加方法,以确保代码的可读性、可维护性和性能。
|
1月前
构造函数的参数有哪些限制和注意事项?
在使用构造函数参数时,需要综合考虑各种因素,确保参数的合理使用和正确处理,以保证类的正常运行和功能实现。
|
5月前
|
Java
怎么用super调用超类构造函数?
Java 中的 `super` 关键字用于子类引用父类的构造函数和成员。当子类构造函数需要调用父类的构造函数时,`super` 须作为第一条语句,如 `super(param列表);`,这允许子类初始化父类的属性。示例中,`BoxWeight` 类通过 `super(w, h, d)` 调用 `Box` 的构造函数来设置尺寸,而 `BoxWeight` 自己仅设置重量。`super` 也可用于访问被子类隐藏的父类成员,实现封装。
|
7月前
|
数据安全/隐私保护 C++
C++ 构造函数实战指南:默认构造、带参数构造、拷贝构造与移动构造
C++中的构造函数是特殊成员函数,用于对象初始化。类型包括默认构造函数(无参数)、带参数构造函数、拷贝构造函数和移动构造函数。默认构造函数设置对象默认状态,带参数构造函数允许传递初始化值。拷贝构造函数复制已有对象,移动构造函数高效转移资源。构造函数的访问权限可控制为public、private或protected。理解构造函数有助于编写健壮的C++代码。关注公众号`Let us Coding`获取更多内容。
112 0
|
编译器 C++
C++关于参数是对象时要调用拷贝构造函数进行传参的问题探讨
C++关于参数是对象时要调用拷贝构造函数进行传参的问题探讨
275 0
|
Java
【Groovy】循环控制 ( Java 语法循环 | 默认的 IntRange 构造函数 | 可设置翻转属性的 IntRange 构造函数 | 可设置是否包含 to 的构造函数 | 0..9 简写 )(二·)
【Groovy】循环控制 ( Java 语法循环 | 默认的 IntRange 构造函数 | 可设置翻转属性的 IntRange 构造函数 | 可设置是否包含 to 的构造函数 | 0..9 简写 )(二)
153 0
|
Java
【Groovy】循环控制 ( Java 语法循环 | 默认的 IntRange 构造函数 | 可设置翻转属性的 IntRange 构造函数 | 可设置是否包含 to 的构造函数 | 0..9 简写 )(一)
【Groovy】循环控制 ( Java 语法循环 | 默认的 IntRange 构造函数 | 可设置翻转属性的 IntRange 构造函数 | 可设置是否包含 to 的构造函数 | 0..9 简写 )(一)
162 0
【错误记录】反射时调用方法及成员报错 ( 执行反射方法 | 设置反射的成员变量 | 设置方法/成员可见性 )
【错误记录】反射时调用方法及成员报错 ( 执行反射方法 | 设置反射的成员变量 | 设置方法/成员可见性 )
193 0
|
Java 编译器
重载(overload) 和重写(override) 的区别?重载的方法能否根据返回类型进行区分?
重载(overload) 和重写(override) 的区别?重载的方法能否根据返回类型进行区分?
1220 0