重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。
错误示例:
替代方法:使用JavaBeans模式
本节建议使用的是Builder模式:
Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。
但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)
错误示例:
- // Telescoping constructor pattern - does not scale well! - Pages 11-12
- 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);
- }
- 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 = carbohydrate;
- }
- public static void main(String[] args) {
- NutritionFacts cocaCola =
- new NutritionFacts(240, 8, 100, 0, 35, 27);
- }
- }
替代方法:使用JavaBeans模式
- // JavaBeans Pattern - allows inconsistency, mandates mutability - Pages 12-13
- 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);
- }
- }
本节建议使用的是Builder模式:
- // Builder Pattern - Pages 14-15
- 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();
- }
- }
Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。
但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)