Effective Java 第三版——2. 当构造方法参数过多时使用builder模式 (3)

请注意,每个子类builder中的build方法被声明为返回正确的子类:NyPizza.Builder的build方法返回NyPizza,而Calzone.Builder中的build方法返回Calzone。 这种技术,其一个子类的方法被声明为返回在超类中声明的返回类型的子类型,称为协变返回类型( covariant return typing)。 它允许客户端使用这些builder,而不需要强制转换。

这些“分层builder”的客户端代码基本上与简单的NutritionFacts builder的代码相同。为了简洁起见,下面显示的示例客户端代码假设枚举常量的静态导入:

NyPizza pizza = new NyPizza.Builder(SMALL) .addTopping(SAUSAGE).addTopping(ONION).build(); Calzone calzone = new Calzone.Builder() .addTopping(HAM).sauceInside().build();

builder对构造方法的一个微小的优势是,builder可以有多个可变参数,因为每个参数都是在它自己的方法中指定的。或者,builder可以将传递给多个调用的参数聚合到单个属性中,如前面的addTopping方法所演示的那样。

Builder模式非常灵活。 单个builder可以重复使用来构建多个对象。 builder的参数可以在构建方法的调用之间进行调整,以改变创建的对象。 builder可以在创建对象时自动填充一些属性,例如每次创建对象时增加的序列号。

Builder模式也有缺点。为了创建对象,首先必须创建它的builder。虽然创建这个builder的成本在实践中不太可能被注意到,但在性能关键的情况下可能会出现问题。而且,builder模式比伸缩构造方法模式更冗长,因此只有在有足够的参数时才值得使用它,比如四个或更多。但是请记住,如果希望在将来添加更多的参数。但是,如果从构造方法或静态工厂开始,并切换到builder,当类演化到参数数量失控的时候,过时的构造方法或静态工厂就会面临尴尬的处境。因此,所以,最好从一开始就创建一个builder。

总而言之,当设计类的构造方法或静态工厂的参数超过几个时,Builder模式是一个不错的选择,特别是如果许多参数是可选的或相同类型的。客户端代码比使用伸缩构造方法(telescoping constructors)更容易读写,并且builder比JavaBeans更安全。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywsxg.html