构建者模式用于构造对象,适合于:当构造对象时需要大量的可选参数。在这方面静态工厂方法和构造器都不是很擅长,因为在这种情况下原本不想设置的参数,也必须传递值。随着参数的增加,这种问题会更加严重,尤其是当参数中包含相同的数据类型时,使用者必须详细阅读API才能防止误传参数。
对于大量可选参数的情况,通常习惯使用重叠构造器或者是使用JavaBeans模式。
场景:考虑使用一个类表示食品的营养成分标签。包含如下几个必需域:每份的含量、每罐的含量以及每份的卡路里;还包含多个可选域:总脂肪量、胆固醇、钠等。
1.重叠构造器
这里,提供一个只有必需参数的构造器,其他的构造器在此基础上增加一个、两个。。。可选参数,通过构造器链进行参数的设置。当创建对象时,利用参数列表最短的构造器即可。但这些参数中有可能包含一些跟不想设置的参数,必须传入默认值。当参数列表包含连续的相同类型的参数时,如果客户端不小心颠倒了参数的顺序,编译器是不会发现的,只有在运行时才会出错。
2.JavaBeans
采用传统JavaBeans模式,调用无参构造器实例化一个对象,然后调用需要的setter方法进行参数的设置,这样构造过程被放在了多个调用中,很可能使对象处于不一致的状态。而且还有一点就是因为setter方法的存在,JavaBeans不能实现对象的不可变性,客户端可以调用setter方法改变对象的状态。
3.Builder模式
Builder模式用于封装一个产品的构造过程,并允许按步骤实现。运用这种方法,可以具有JavaBeans的可读性,并且可以像使用构造器或者静态工厂方法那样产生不可变对象。客户端利用必需的参数调用构造器或静态工厂方法,得到一个Builder对象。然后再在Builder对象调用类似JavaBeans的setter方法进行可选参数的设置,这样构造一个对象所需的参数都保存在Builder对象中,然后用Builder对象实例化一个不可变对象。
与构造器相比,Builder的优势在于它可读性更强,并且可以具有多个可变参数。因为每个可选参数的设置方法都可以编程相应的可变参数,而构造器只能有一个。还有就是Builder更加灵活,可以用一个Builder对象实例化多个对象。
当然由于在构造对象时需要先实例化Builder对象,这样会带来一些性能损耗。不过当有多个可选参数时,Builder模式提供的灵活性、可读性和安全性更好,是一个不错的选择