第2条:遇到多个构造器参数时要考虑用构造器
来源:互联网 发布:vb系列振动电机报价 编辑:程序博客网 时间:2024/05/17 00:06
当我们看帮助文档的时候,有没有想过它是怎么设计构造器的?为什么这么设置?这样设计有什么好处?
第一种情况:重叠构造器(telescoping constructor)
package com.wisdom.effective.java;/** * * @author Wisdom 第2条:遇到多个构造器参数时要考虑用构造器 */public class TelescopingConstructin { public static void main(String[] args) { NutritionFacts nf1 = new NutritionFacts(1, 1); NutritionFacts nf2 = new NutritionFacts(1, 1, 1); NutritionFacts nf3 = new NutritionFacts(1, 1, 1, 1); NutritionFacts nf4 = new NutritionFacts(1, 1, 1, 1, 1); NutritionFacts nf5 = new NutritionFacts(1, 1, 1, 1, 1, 1); System.out.println(nf1); System.out.println(nf2); System.out.println(nf3); System.out.println(nf4); System.out.println(nf5); }}class NutritionFacts { private int servingSize; // (ml) required 份量 private int servings; // (ml) required 份 private int calories; // optional 卡路里 private int fat; // (g) optional 脂肪 private int sodium; // (mg) optional 钠 private int carbohydrate; // (g) optional 糖类 public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 0); } public void setCarbohydrate(int carbohydrate) { this.carbohydrate = carbohydrate; } 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 sadium) { this(servingSize, servings, calories, fat, sadium, 0); } public NutritionFacts(int servingSize, int servings, int calories, int fat, int sadium, int carbohydrate) { this.servingSize = servingSize; this.servings = servings; this.calories = calories; this.fat = fat; this.sodium = sadium; this.carbohydrate = carbohydrate; }}
缺陷:重叠构造器模式可行,但是当有许多参数的时候,客户端会很难编写;如果客户端不小心点到了其中两个参数的顺序,编译器也不会出错,但是程序在运行时会出现错误的行为。
第二种情况:JavaBeans模式
package com.wisdom.effective.java;/** * * @author Wisdom Effective Java中文版 第2条:遇到多个构造器参数时要考虑用构造器 */public class TelescopingConstructin_2 { public static void main(String[] args) { NutritionFacts_2 nf1 = new NutritionFacts_2(); nf1.setServingSize(240); nf1.setServings(8); nf1.setCalories(100); nf1.setSodium(35); nf1.setCarbohydrate(27); System.out.println(nf1); }}class NutritionFacts_2 { private int servingSize = -1; // (ml) required 份量 private int servings = -1; // (ml) required 份 private int calories = 0; // optional 卡路里 private int fat = 0; // (g) optional 脂肪 private int sodium = 0; // (mg) optional 钠 private int carbohydrate = 0; // (g) optional 糖类 public NutritionFacts_2() { } public void setServingSize(int servingSize) { this.servingSize = servingSize; } public void setServings(int servings) { this.servings = servings; } public void setCalories(int calories) { this.calories = calories; } public void setFat(int fat) { this.fat = fat; } public void setSodium(int sodium) { this.sodium = sodium; } public void setCarbohydrate(int carbohydrate) { this.carbohydrate = carbohydrate; }}
缺陷:1、因为构造过程被分为几个调用中,在构造过程中JavaBeans可能处于不一致的状态。2、JavaBeans模式组织了把类做成不可变的可能,这就需要程序猿付出额外的努力来确保他的线程安全。
第三种情况:Builder模式(即能保证像重叠构造器那样的安全性,也能保证像JavaBeans模式那么好的可读性),他不直接生成想要的对象,而是让客户端利用所有必要的参数调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。这个builder是它构建的类的静态成员。
package com.wisdom.effective.java;/** * * @author Wisdom Effective Java中文版 第2条:遇到多个构造器参数时要考虑用构造器 */public class TelescopingConstructin_3 { public static void main(String[] args) { NutritionFacts_3 cocaCola = new NutritionFacts_3.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).build(); System.out.println(cocaCola); }}class NutritionFacts_3 { private int servingSize; // (ml) required 份量 private int servings; // (ml) required 份 private int calories; // optional 卡路里 private int fat; // (g) optional 脂肪 private int sodium; // (mg) optional 钠 private int carbohydrate; // (g) optional 糖类 public static class Builder { // Required private int servingSize; private int servings; // Optional private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; } public NutritionFacts_3 build() { return new NutritionFacts_3(this); } } private NutritionFacts_3(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; }}
好处:客户端代码很容易编写,更为重要的是易于阅读。builder模式模拟了具名的可选参数,就像Ada和Python中的一样。
优化版:
package com.wisdom.effective.java;/** * * @author Wisdom Effective Java中文版 第2条:遇到多个构造器参数时要考虑用构造器 */public class TelescopingConstructin_3 { public static void main(String[] args) { NutritionFacts_3 cocaCola = new NutritionFacts_3.Builder(240, 8) .calories(100).sodium(35).carbohydrate(27).builder(); System.out.println(cocaCola); }}interface BuilderInter<T>{ public T builder();}class NutritionFacts_3 { private int servingSize; // (ml) required 份量 private int servings; // (ml) required 份 private int calories; // optional 卡路里 private int fat; // (g) optional 脂肪 private int sodium; // (mg) optional 钠 private int carbohydrate; // (g) optional 糖类 public static class Builder implements BuilderInter<NutritionFacts_3>{ // Required private int servingSize; private int servings; // Optional private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; }// public NutritionFacts_3 build() {// return new NutritionFacts_3(this);// } public NutritionFacts_3 builder() { return new NutritionFacts_3(this); } } private NutritionFacts_3(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; }}
1 0
- 第2条:遇到多个构造器参数时要考虑用构造器
- 第2条:遇到多个构造器参数时要考虑用构造器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条 遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- 第2条:遇到多个构造器参数时要考虑用构建器
- [Effective Java] 第2条 遇到多个构造器参数时要考虑用构造器
- effective java读书札记值第2条:遇到多个构造器参数时要考虑用构造器
- 第2条:遇到多个构造器参数时,考虑用构建器。
- Effective java第二条:遇到多个构造器参数时要考虑用构造器
- EffectiveJava 第2条 :遇到多个构造器参数时要考虑用构建器(2)
- EffectiveJava 第2条 :遇到多个构造器参数时要考虑用构建器(1)
- [EJ读书笔记]第2条:遇到多个构造器参数时要考虑用构建器
- 《Effective java》读书记录-第2条-遇到多个构造器参数时要考虑用构建器
- 第一篇
- POJ2586
- adb命令调试报错及解决
- JNI的使用
- SVN新建外链和删除外链
- 第2条:遇到多个构造器参数时要考虑用构造器
- bash shell脚本编程学习总结一
- MVC设计模式
- Java基础02 java的访问控制以及与C#的异同
- hadoop源码编译环境安装配置
- android.content.res.Resources$NotFoundException: Unable to find resource ID 0#0xffffffff
- HttpURLConnection+URl网络请求
- android studio for android learning (二十 )android中this、context等关键概念理解全解
- 逻辑中断