前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Java高效编程(2):面对多个构造参数时考虑使用构建器模式

Java高效编程(2):面对多个构造参数时考虑使用构建器模式

作者头像
蒙娜丽宁
发布2024-11-23 15:44:32
发布2024-11-23 15:44:32
7100
代码可运行
举报
文章被收录于专栏:极客起源极客起源
运行总次数:0
代码可运行

在Java编程中,静态工厂和构造函数都存在一个局限性:当可选参数数量较多时,它们的扩展性较差。以表示食品包装上营养成分标签的类为例,这些标签包含几个必需字段——如份量大小、每容器的份数和每份的卡路里——以及超过二十个可选字段,例如总脂肪、饱和脂肪、反式脂肪、胆固醇、钠等。大多数产品只有少数这些可选字段的值不为零。

在这种情况下,应该如何编写构造函数或静态工厂呢?传统上,程序员采用了“ telescoping constructor pattern”(逐层构造函数模式),这种模式提供了一个只接受必需参数的构造函数、一个接受一个可选参数的构造函数、一个接受两个可选参数的构造函数,依此类推,最终形成一个接受所有可选参数的构造函数。以下是这种模式的示例,为了简洁,仅显示了四个可选字段:

代码语言:javascript
代码运行次数:0
复制
// 逐层构造函数模式 - 扩展性差! public class NutritionFacts {     private final int servingSize;  // (mL)  必需     private final int servings;      // 必需     private final int calories;      // 可选     private final int fat;           // 可选     private final int sodium;        // 可选     private final int carbohydrate;  // (g/serving) 可选      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);     } } 

虽然这种方法在小范围内可行,但随着可选参数的增多,构造函数的数量迅速增加,导致代码难以管理和维护。

解决方案:构建器模式

为了应对这一挑战,可以采用构建器模式。这种模式允许逐步构建对象,并在创建时提供灵活性和可读性。下面是使用构建器模式重构 NutritionFacts 类的示例:

代码语言:javascript
代码运行次数:0
复制
public class NutritionFacts {     private final int servingSize;  // (mL)     private final int servings;     private final int calories;      // 可选     private final int fat;           // 可选     private final int sodium;        // 可选     private final int carbohydrate;  // 可选      private NutritionFacts(Builder builder) {         this.servingSize = builder.servingSize;         this.servings = builder.servings;         this.calories = builder.calories;         this.fat = builder.fat;         this.sodium = builder.sodium;         this.carbohydrate = builder.carbohydrate;     }      public static class Builder {         private final int servingSize;  // (mL)         private final int servings;         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 build() {             return new NutritionFacts(this);         }     } } 
使用示例

使用构建器模式创建 NutritionFacts 实例变得简单且清晰:

代码语言:javascript
代码运行次数:0
复制
NutritionFacts nutritionFacts = new NutritionFacts.Builder(240, 2)         .calories(100)         .fat(5)         .sodium(10)         .carbohydrate(20)         .build(); 

这种方式不仅提高了可读性,还允许你在创建对象时轻松选择性地设置参数,从而避免了构造函数数量暴增的问题。构建器模式是处理多个构造参数的理想选择,特别是在面对许多可选字段时。

- EOF -

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-11-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客起源 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决方案:构建器模式
  • 使用示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档