[Effective|[Effective Java]-多参数构造时考虑用构建器

ps:代码后期贴。
静态工厂(static factory methon)和构造器共同局限性:不能很好的扩展到大量的可选参数。
一般情况下很多程序员使用重叠构造器模式(telescoping constructor pattern)
优点:易于编写、易于调用,参数数量较少时适用。
缺点:参数过多时容易失控,比如类型相同的参数,不小心颠倒了其中两个参数的位置,编译时不会报错,而实际上运行时就会出现错误。
第二种方法,JavaBeans模式(JavaBeans pattern)
实现过程:使用无参构造器创建对象,调用setter方法设置必要/可选参数。
优点:创建实例容易,代码可读性高。
缺点:
1、构造对象的过程被分成了几个调用导致JavaBean可能处于不一致的状态。类无法通过校验构造器参数的有效性来保证一致性,导致调试比较困难。
2、JavaBeans模式阻止了把类做成不可变的可能,会导致线程不安全,需要额外的控制来保持线程安全(在构造完成前手工“冻结”对象,但这个方式很蠢而且无法编译器无法确保程序员是否在使用之前先在对象上调用freeze方法)。
【[Effective|[Effective Java]-多参数构造时考虑用构建器】第三种方法,Builder模式(Builder Pattern)即建造者模式或者生成器模式,既能保证像重叠构造器模式那样的安全性,又能保证像JavaBeans模式那样的可读性。
实现过程:不直接生成想要的对象,使用构造器/静态工厂来生成带有必要参数的builder对象,然后在builder对象上调用类似setter的方法,设置可选参数,最后调用无参的build方法来生成不可变的对象。
优点:
1、调用会很容易,且可读性高。
2、比构造器好的是,可以有多个可变参数。而构造器只能有一个可变参数。
3、可利用单个builder构建多个对象。builder的参数可以在创建对象期间进行调整,且可自动填充某些域(比如每次创建对象时自动增添序列号)。
4、可对参数强加约束条件。方法一:build方法中检验这些约束条件,在对象域中进行检验,如果违反了约束条件,build方法抛出IllegalStateException。方法二:用多个setter方法对某个约束条件必须持有的所有参数进行检查,如果不满足,setter方法抛出IllegalStateException。好处就是在setter中就可以检验二不是等build时才发现错误。
缺点:
1、有额外的开销。为了创建对象需要先新建builder,虽然开销比较小,但是在十分注重性能的情况下会成为问题。
2、代码冗长,因此只适合4个或者更多参数的情况。但是如果预料到将来可能有更多的参数,推荐在一开始的时候就使用建造者模式,因为等到实际出现多个参数时再添加,就会变得难看,因为有一些旧的构造器或者静态工厂。

    推荐阅读