将构造和表示分离,目标对象是抽象出来的比较简单便于理解的类,而从现有条件构造出对象的过程很复杂。这个描述还没有到点上。来一个比较使用的场景。
一个场景
例如需要构造一个Person类,有name,id,age,sex,height,weight,hobby。
其中name和id是必须的,其他是可选的。如果只能使用构造方法创建,那么构造方法根据不同的属性要求组合起来可以有很多种,实在太烦了,而调用时的代码可读性也是很差的。
一个解决办法是使用name和id作为构造函数,为所有属性提供setter方法。这样就能解决上面构造方法太多的问题。
但是也有缺点,setter都暴露出去了,这样相当于所有属性都暴露了,有潜在的数据不一致的问题,不好解决线程安全问题。
这时候builder模式登场了:PersonBuilder,使用name和id作为构造器,提供各种set方法和最终的build方法,build返回的Person对象,可以是各种属性都是final的,本身的各种属性也不必是用setter暴露出来。
——因为有些属性必须通过外部传入,而又不想被修改。
可以看出Builder模式是把构造器的设计,分离出来并进行加强——因为一个类的构造器本身不需要承担那么强的责任。
这就是构造过程复杂的所指——只想构造器传入属性,而构造器又多种参数搭配。
PS,Builder模式常有链式调用风格
常见Builder
- StringBuilder很典型,String的内部char[] value是final的,而构造一个String的参数搭配可以无限复杂。
- MyBatis的SqlSessionFactoryBuilder,这个场景只是单纯的从参数到目标对象之间需要经过比较复杂的逻辑。例如一般传入的参数都是一个xml,形式可以是多种多样,但是只是xml,其中有一些配置是有default的,有些是必选的。还有parse和校验之类的过程。因此,单独抽取一个Builder来建造目标对象是很合适的。