比如要创建这么一个对象:

    创建对象的方式:
    1.可伸缩构造方法,但是参数过多会变得难以阅读和维护,读者不知道这些值是什么意思,并且必须仔细地去数参数才能找到答案。一长串相同类型的参数可能会导致一些细微的 bug。如果客户端不小心写反了两个这样的参数,编译器并不会报错,但是程序在运行时会出现错误行为。

    1. // Telescoping constructor pattern - does not scale well!
    2. public class NutritionFacts {
    3. private final int servingSize; // (mL) required
    4. private final int servings; // (per container) required
    5. private final int calories; // (per serving) optional
    6. private final int fat; // (g/serving) optional
    7. private final int sodium; // (mg/serving) optional
    8. private final int carbohydrate; // (g/serving) optional
    9. public NutritionFacts(int servingSize, int servings) {
    10. this(servingSize, servings, 0);
    11. }
    12. public NutritionFacts(int servingSize, int servings,
    13. int calories) {
    14. this(servingSize, servings, calories, 0);
    15. }
    16. public NutritionFacts(int servingSize, int servings,
    17. int calories, int fat) {
    18. this(servingSize, servings, calories, fat, 0);
    19. }
    20. public NutritionFacts(int servingSize, int servings,
    21. int calories, int fat, int sodium) {
    22. this(servingSize, servings, calories, fat, sodium, 0);
    23. }
    24. public NutritionFacts(int servingSize, int servings,
    25. int calories, int fat, int sodium, int carbohydrate) {
    26. this.servingSize = servingSize;
    27. this.servings = servings;
    28. this.calories = calories;
    29. this.fat = fat;
    30. this.sodium = sodium;
    31. this.carbohydrate = carbohydrate;
    32. }
    33. }

    2.通过java bean模式,在构造过程中 JavaBean 可能处于不一致的状态

    1. public class NutritionFacts {
    2. // Parameters initialized to default values (if any)
    3. private int servingSize = -1; // Required; no default value
    4. private int servings = -1; // Required; no default value
    5. private int calories = 0;
    6. private int fat = 0;
    7. private int sodium = 0;
    8. private int carbohydrate = 0;
    9. public NutritionFacts() { }
    10. // Setters
    11. public void setServingSize(int val) { servingSize = val; }
    12. public void setServings(int val) { servings = val; }
    13. public void setCalories(int val) { calories = val; }
    14. public void setFat(int val) { fat = val; }
    15. public void setSodium(int val) { sodium = val; }
    16. public void setCarbohydrate(int val) { carbohydrate = val; }
    17. }
    18. NutritionFacts cocaCola = new NutritionFacts();
    19. cocaCola.setServingSize(240);
    20. cocaCola.setServings(8);
    21. cocaCola.setCalories(100);
    22. cocaCola.setSodium(35);
    23. cocaCola.setCarbohydrate(27);

    3.通过建造者模式,即能保证像重叠构造器的安全性,也能保证像 JavaBeans 模式那么好的可读性

    1. public class NutritionFacts {
    2. private final int servingSize;
    3. private final int servings;
    4. private final int calories;
    5. private final int fat;
    6. private final int sodium;
    7. private final int carbohydrate;
    8. public static class Builder {
    9. // Required parameters
    10. private final int servingSize;
    11. private final int servings;
    12. // Optional parameters - initialized to default values
    13. private int calories = 0;
    14. private int fat = 0;
    15. private int sodium = 0;
    16. private int carbohydrate = 0;
    17. public Builder(int servingSize, int servings) {
    18. this.servingSize = servingSize;
    19. this.servings = servings;
    20. }
    21. public Builder calories(int val) {
    22. calories = val;
    23. return this;
    24. }
    25. public Builder fat(int val) {
    26. fat = val;
    27. return this;
    28. }
    29. public Builder sodium(int val) {
    30. sodium = val;
    31. return this;
    32. }
    33. public Builder carbohydrate(int val) {
    34. carbohydrate = val;
    35. return this;
    36. }
    37. public NutritionFacts build() {
    38. return new NutritionFacts(this);
    39. }
    40. }
    41. private NutritionFacts(Builder builder) {
    42. servingSize = builder.servingSize;
    43. servings = builder.servings;
    44. calories = builder.calories;
    45. fat = builder.fat;
    46. sodium = builder.sodium;
    47. carbohydrate = builder.carbohydrate;
    48. }
    49. }
    50. //使用
    51. NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
    52. .calories(100).sodium(35).carbohydrate(27).build();