首页 > 其他分享 >当构造方法参数过多时使用 builder 模式

当构造方法参数过多时使用 builder 模式

时间:2022-10-27 14:57:02浏览次数:46  
标签:构造方法 int builder calories private servings 过多时 servingSize public

构造方法参数过多的解决方法
提出问题:

例如:食品影响成分标签

  1. 必需的属性——每次建议的摄入量,每罐的份量和每份卡路里,
  2. 以及超过20 个可选的属性——总脂肪、饱和脂肪、反式脂肪、胆固醇、钠等等。

大多数产品只有这些可选字段中的少数, 且具有非零值。

应该为这样的类编写什么样的构造方法或静态工厂?

1. 可伸缩构造方法模式(Telescoping constructor pattern)

在这种模式中,
首先提供一个只有必需参数的构造方法,
接着提供增加了一个可选参数的构造函数,
然后提供增加了两个可选参数的构造函数,等等,
最终在构造函数中包含所有必需和可选参数。
以下就是它在实践中的样子。为了简便起⻅,只显示了四个可选属性:

// Telescoping constructor pattern - does not scale well!
public class NutritionFacts {
    private final int servingSize;  // (mL)            required
    private final int servings;     // (per container) required
    private final int calories;     // (per serving)   optional
    private final int fat;          // (g/serving)     optional
    private final int sodium;       // (mg/serving)    optional
    private final int carbohydrate; // (g/serving)     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);
    }
    
}

缺点:
1、参数扩展性差,随着参数数量的增加,代码维护成本大大增加;
2、增加使用复杂性,难以理解,参数过多时必须仔细对比参数顺序。

2. JavaBeans 模式

当在构造方法中遇到许多可选参数时,另一种选择是 JavaBeans 模式,在这种模式中,调用一个无参的构造方法来创建对象,然后调用 setter 方法来设置每个必需的参数和可选参数:

// JavaBeans Pattern - allows inconsistency, mandates mutability  (pages 11-12)
public class NutritionFacts {
    // Parameters initialized to default values (if any)
    private int servingSize  = -1; // Required; no default value
    private int servings     = -1; // Required; no default value
    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);
    }
}

优点:
这种模式没有伸缩构造方法模式的缺点,易于理解。

缺点:
破坏了类的不可变性,需要程序员增加工作以确保线程安全。

不可变类简单来说是它的实例不能被修改的类。包含在每个实例中的所有信息在对象的生命周期中是固定的。

3. Builder Pattern

标签:构造方法,int,builder,calories,private,servings,过多时,servingSize,public
From: https://www.cnblogs.com/weldonh/p/16832235.html

相关文章