Effective Java
来源:互联网 发布:jquery定义数组并赋值 编辑:程序博客网 时间:2024/06/05 17:41
读书笔记 仅供参考
静态工厂和构造器的局限性
不能很好地扩展到大量的可选参数
重叠构造器模式
提供一个只有必要参数的构造器,其余构造器逐渐增加可选参数,直到最后一个构造器包含所有可选参数
public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; //两个必要参数 public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 0); } //一个可选参数 public NutritionFacts(int servingSize, int servings , int calories) { this(servingSize, servings, calories, 0); } //两个可选参数 public NutritionFacts(int servingSize, int servings , int calories, int fat) { this(servingSize, servings, calories, fat ,0); } //所有可选参数 public NutritionFacts(int servingSize, int servings , int calories, int fat, int sodium) { this.servingSize = servingSize; ... this.sodium = sodium; }}
随着参数的增加,程序很快会失去控制,客户端代码会很难编写,并且难以阅读。
JavaBeans 模式
即利用 setter 和 getter 方法来设置参数,我从最开始写 java 代码就使用这种方式。这种方式与前后两种还有一个区别:属性不能设为 final,即不可作为不可变类。
public class NutritionFacts { private int servingSize; private int servings; private int calories; private int fat; private int sodium; public void setServingSize(int servingSize) { this.servingSize = servingSize; } ...}
因为构造过程被分到多个调用中,在构造过程中 JavaBeans 可能处于不一致的状态,试图使用不一致状态的对象,将会导致失败。另外一点不足:JavaBeans 模式组织了将类作为不可变类的可能,需要付出额外努力确保线程安全
ps:不一致的状态:不是很理解这个概念,在网上查询的结果是:同一个构造器产生的对象,但是最后对象的属性却大相径庭。或者理解为,在还没有为对象 set 必要属性的时候,就使用对象,会导致错误(这个倒是我时常会发生的错误)。
Builder 模式
先产生一个 builder 对象,再在 builder 对象上调用类似 setter 的方法,设置可选参数,最后利用无参的 build 方法生成不可变的对象。
public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; //必选参数 private final int servingSize; private final int servings; //可选参数,要有默认值 private int calories = 0; private int fat = 0; private int sodium = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { caolries = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; ... }}//调用方式NutritionFacts fact = new NutritionFacts.Builder(240, 8). calories(100).sodium(35).build();
builder 可以对参数进行检验,如果违反了约束就抛出异常。也可以在 setter 方法(builder 模式的 setter)中对参数进行检验,不在 builde() 方法中检验。
设置了参数的 builder 生成了一个抽象工厂,用泛型满足所有的 builder
public interface Builder<T> { public T build();}
Builder 模式的不足在于创建 builder 的性能损耗,在十分注重性能的情况下,会成为问题, Builder 模式比重叠构造器还冗长,所有只有在有很多参数的情况下才使用。
- Effective Java
- Effective Java
- Effective Java
- Effective Java
- effective java
- effective java
- Effective Java
- Effective Java
- effective java
- Effective Java
- Effective Java
- 《Effective Java》
- effective java
- effective java
- Effective Java
- Effective Java
- 《Effective java》
- Effective Java
- 一起Talk Android吧(第四十七回:Android中的Fragment十二)
- 点亮细胞151-160
- JZOJ 5434. 【NOIP2017提高A组集训10.30】Matrix
- BC95透传模块
- Faster RCNN训练出现问题:smooth_L1_loss_layer.cpp:28] Check failed: bottom[0]->channels() == bottom[1]->cha
- Effective Java
- git reset命令
- 点亮细胞161-170
- 非递归前,中,后序遍历二叉树
- 学习Angularjs<一>
- java 编程思想 第三章 练习14
- 15个必知的Android开发者选项
- 计算机网络之Cisco Packet Tracer模拟器使用
- 点亮细胞171-180