多参构造器与Builder模式
2013-10-28 16:50
155 查看
一、静态工厂方法与构造器共同的局限性
不能很好的扩展到大量的可选参数,这个很悲剧的,我一般使用java bean,不管合适不合适,没考虑线程安全哈。
二、有多个可选参数对象的实例化方法
1、重叠构造器:提供一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个构造器有两个可选参数,以此类推,最后一个构造器包含所有的可选参数。
当想要创建实例的时候,只需使用参数列表最短的构造器,但有时需要设置很多本来不需要设置的参数,参数少了还可以,如果多的话就成灾难了。
点评:重叠构造器模式可行,但是当有许多参数的时候,客户代会很难编写,并且仍然较难以阅读。参数顺序及代表意义很难分辨,这需要良好的文档支持,但一般看文档比较费事。
2、JavaBean模式:调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。
优点:弥补了重叠构造器的不足,创建实例很容易,代码更容易阅读,我一般就是采用这种方式,哈哈。
缺点:
1、对象构造过程被分配到几个调用中,在构造过程中JavaBean可能处于不一致的状态,这样在多线程环境下容易产生线程安全问题。
2、JavaBean模式阻止了把类做成不可变类的可能,这需要我们自己付出额外努力来确保对象的线程安全。不可变类就是爽啊,不用考虑线程安全问题。无状态类也不用考虑,呵呵。貌似可以通过在构造完成之前,先冻结对象,构造完成之后再使用,这操作起来比较麻烦,很少这样做!
3、Builder模式:不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器或静态工厂,得到一个builder对象,然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。通常,这个builder是它构造的类的静态成员类。
优点:
1、即能保证像重叠构造器模式那样的安全性,又能保证像JavaBean模式那么好的可读性。
2、builder模式模拟了具名的可选参数,就像Ada和Python一样。没用过这两种语言,不知道怎么回事,呵呵。
3、builder模式可以对其参数强加约束条件。build方法可以检验这些约束条件,将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对它们进行检验。如果违反了任何约束条件,build方法都应该抛出IllegalStateException。异常的信息应该显示出违反了哪个约束条件。
缺点:
1、为了创建对象,必须先创建它的构造器。注重性能的情况下,可能就完蛋了。
2、Builder模式比重叠构造器更加冗长,一般在很多参数时才会使用,比如4个或更多。
三、最佳实践
1、如果类的构造器或静态工厂中有多个参数,设计这样类时,最好使用Builder模式,特别是当大多数参数都是可选的时候。
2、如果现在不能确定参数的个数,最好一开始就使用构建器即Builder模式。
不能很好的扩展到大量的可选参数,这个很悲剧的,我一般使用java bean,不管合适不合适,没考虑线程安全哈。
二、有多个可选参数对象的实例化方法
1、重叠构造器:提供一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个构造器有两个可选参数,以此类推,最后一个构造器包含所有的可选参数。
/** * 食品营养成分标签类 */ public class NutritionFacts { private final int servingSize; //(ml) required private final int servings; //(per container) required private final int calories; // optional private final int fat; //(g) optional private final int sodium; //(mg) optional private final int carbohydrate; //(g) optional /** * 只含必需项 */ 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,servings,calories,fat,sodium,0); } /** * 含有所有可选项(4个) */ public NutritionFacts(int servingSize,int servings,int calories,int fat,int sodium, int carbohydrate){ this.servingSize = servingSize; this.servings = servings; this.calories = calories; this.fat = fat; this.sodium = sodium; this.carbohydrate = calories; } }
当想要创建实例的时候,只需使用参数列表最短的构造器,但有时需要设置很多本来不需要设置的参数,参数少了还可以,如果多的话就成灾难了。
//这样构造方法需要设置一些本不需要设置的参数 NutritionFacts nf = new NutritionFacts(120, 230, 456, 0, 30, 40);
点评:重叠构造器模式可行,但是当有许多参数的时候,客户代会很难编写,并且仍然较难以阅读。参数顺序及代表意义很难分辨,这需要良好的文档支持,但一般看文档比较费事。
2、JavaBean模式:调用一个无参构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。
public class NutritionFacts { // Parameters initialized to default values (if any) private int servingSize = -1; // Required; no default value private int servings = -1; // " " " " private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public NutritionFacts() { } // Setters public void setServingSize(int val) { servingSize = val; } public void setServings(int val) { servings = val; } public void setCalories(int val) { calories = val; } public void setFat(int val) { fat = val; } public void setSodium(int val) { sodium = val; } public void setCarbohydrate(int val) { carbohydrate = val; } public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(240); cocaCola.setServings(8); cocaCola.setCalories(100); cocaCola.setSodium(35); cocaCola.setCarbohydrate(27); } }
优点:弥补了重叠构造器的不足,创建实例很容易,代码更容易阅读,我一般就是采用这种方式,哈哈。
缺点:
1、对象构造过程被分配到几个调用中,在构造过程中JavaBean可能处于不一致的状态,这样在多线程环境下容易产生线程安全问题。
2、JavaBean模式阻止了把类做成不可变类的可能,这需要我们自己付出额外努力来确保对象的线程安全。不可变类就是爽啊,不用考虑线程安全问题。无状态类也不用考虑,呵呵。貌似可以通过在构造完成之前,先冻结对象,构造完成之后再使用,这操作起来比较麻烦,很少这样做!
3、Builder模式:不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器或静态工厂,得到一个builder对象,然后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后,客户端调用无参的build方法来生成不可变的对象。通常,这个builder是它构造的类的静态成员类。
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 carbohydrate; public static class Builder { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 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 carbohydrate(int val) { carbohydrate = 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; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). calories(100).sodium(35).carbohydrate(27).build(); } }
优点:
1、即能保证像重叠构造器模式那样的安全性,又能保证像JavaBean模式那么好的可读性。
2、builder模式模拟了具名的可选参数,就像Ada和Python一样。没用过这两种语言,不知道怎么回事,呵呵。
3、builder模式可以对其参数强加约束条件。build方法可以检验这些约束条件,将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对它们进行检验。如果违反了任何约束条件,build方法都应该抛出IllegalStateException。异常的信息应该显示出违反了哪个约束条件。
缺点:
1、为了创建对象,必须先创建它的构造器。注重性能的情况下,可能就完蛋了。
2、Builder模式比重叠构造器更加冗长,一般在很多参数时才会使用,比如4个或更多。
三、最佳实践
1、如果类的构造器或静态工厂中有多个参数,设计这样类时,最好使用Builder模式,特别是当大多数参数都是可选的时候。
2、如果现在不能确定参数的个数,最好一开始就使用构建器即Builder模式。
相关文章推荐
- 设计模式(2)-创建型-建造者模式(Builder)
- 设计模式C++实现(6)——建造者模式(Builder)
- .NET设计模式(4):建造者模式(Builder Pattern)
- Object Builder中的Locator究竟是不是采用Composite的模式之我见
- 设计模式(Builder模式)
- 设计模式(三):Builder模式
- .Net设计模式学习笔记(四):建造者模式(Builder Pattern)
- Builder设计模式原理
- Android设计模式——Builder模式
- 设计模式拾荒之创建者模式( Builder Pattern )
- Android--Builder模式
- ※设计模式※→☆创建型模式☆============Builder模式(五)
- Builder模式在Java中的应用
- Builder 模式的变种 类似于AlertDialog
- 设计模式学习笔记(四)——Builder生成器模式
- 阿Sam的设计模式学习笔记---- Builder模式
- builder设计模式学习及应用dialogfragment链式调用封装
- 23设计模式之建造者模式(Builder)
- 建造者(Builder)模式
- java设计模式_Builder模式