第二章 对象的生成和销毁 读书笔记
实体类有很多构造函数的时候,使用 Builder
In summary, the Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if many of the parameters are optional or of identical type. Client code is much easier to read and write with builders than with telescoping constructors, and builders are much safer than JavaBeans.
总的来说,builder 模式适用于实体类有多个构造函数并且参数大于 5 个,参数可选并且参数类型相同的情况。
1 | /** |
多构造函数能够工作,但是对客户端来说多个参数的构造函数在调用和阅读上比较容易出错。
为了解决上面的多构造器模式的弊端,还有一种解决方案是采用 简单构造函数 + setter 的方式
1 |
|
弊端:调用是分散的,类属性可能存在不一致;这种模式不可能把一类做成不可变,需要额外的努力来确保线程安全。
以下是建造者模式的实现
1 | public class NutritionFacts { |
客户端调用代码如下
1 | NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build(); |
多态下使用 Builder 模式
1 | // 父类 |
Builder 模式出了比较冗长之外没有其他坏处,而且扩展性好。
问题
- 使用 final 修饰属性有什么好处?
- 可以保证对应的变量只被赋值一次,并且 final 修饰的变量必须得赋值
PS: 外部类可以访问内部类的私有变量,这个我之前倒是没有想到的
Builder<T extends Builder<T>>
语法- 这种语法叫做 递归类型参数(recursive type parameter), 是泛型的一种,指代泛型参数必须是自己的子类,不理解可以先记着
protected abstract T self();
为什么不直接返回this
?- 亲自写一下就会发现,builder 本身是个抽象类,所以是没有
this
这个指代的
- 亲自写一下就会发现,builder 本身是个抽象类,所以是没有
父类的构造器是
protected
的,不然子类无法继承, 同理toppings
也应该是 protected 的,不然子类根本就访问不了 (´Д` )