遇到多个构造器参数时要考虑使用builder
概述
静态工厂和构造函数都不能很好地扩展到大量的可选参数。
场景
考虑这样一个类——营养成分标签,其中有几个field时必需的,其他则是可选的:
1 | class NutritionFactsOne { |
这样,我们创建一个实例时,就很不容易阅读:
1 | NutritionFactsOne n = new NutritionFactsOne(240, 8, 100, 0, 35, 27); |
当然,也可以考虑用java beans的模式,然后调用setter设置每个必要的参数,已经相关的可选参数。
1 | class NutritionFactsTwo { |
紧接着
1 | NutritionFactsTwo n = new NutritionFactsTwo(); |
但这个使用方式,在多线程的环境下有着致命的缺点,因为这有可能使得对象处于一个不一致的状态。
因此,我们可以使用builder的一种模式:
1 | class NutritionFactsThree { |
builder的setter方法返回builder本身,这样就可以把调用链给连接起来:
1 | NutritionFactsThree n = new NutritionFactsThree.Builder(240, 8) |
优点
- 客户端代码易于理解
- 可以对参数施加约束条件
- builder有多个可变参数
- builder相比javabeans更加安全
总结
如果类的构造器或者静态工厂中具有多个参数,设计类的时候,builder模式应该优先被选择,特别是大多数参数都optional的时候。