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

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

时间:2024-09-26 12:48:44浏览次数:3  
标签:高效 Java int 编程 calories private servings servingSize final

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界

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

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

// 逐层构造函数模式 - 扩展性差!
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 类的示例:

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 实例变得简单且清晰:

NutritionFacts nutritionFacts = new NutritionFacts.Builder(240, 2)
        .calories(100)
        .fat(5)
        .sodium(10)
        .carbohydrate(20)
        .build();

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

标签:高效,Java,int,编程,calories,private,servings,servingSize,final
From: https://blog.csdn.net/nokiaguy/article/details/142553122

相关文章

  • Java线程池详解
    目录前言线程池概述线程池的实现线程池的构造拒绝策略任务队列线程池的工作原理线程池的监控Executors线程池工厂自定义线程池使用线程池的好处应用场景总结本文详细探讨了线程池在并发编程领域的应用,介绍了ThreadPoolExecutor的核心组件、工作原理,线程池的构造......
  • 基于Java+SpringBoot+Mysql陪练系统功能设计与实现一
    一、前言介绍:1.1项目摘要随着互联网技术的飞速发展和普及,网络游戏已成为人们休闲娱乐的重要方式之一。随着游戏玩家群体的不断扩大,游戏内竞争日益激烈,许多玩家为了提升游戏技能、快速升级或享受游戏乐趣,开始寻求外部帮助,如寻找高水平玩家进行陪玩或雇佣代练服务。这一需......
  • 基于Java+SpringBoot+Mysql陪练系统功能设计与实现二
    一、前言介绍:1.1项目摘要随着互联网技术的飞速发展和普及,网络游戏已成为人们休闲娱乐的重要方式之一。随着游戏玩家群体的不断扩大,游戏内竞争日益激烈,许多玩家为了提升游戏技能、快速升级或享受游戏乐趣,开始寻求外部帮助,如寻找高水平玩家进行陪玩或雇佣代练服务。这一需......
  • JavaScript简介及示例
                                                JavaScript简介及使用 一、简介JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为Ja......
  • PTA JAVA语言 6-1 数字翻转
    6-1数字翻转分数10全屏浏览切换布局作者 Ma单位 山东科技大学现需要编写一个方法publicstaticintrNum(intnum)用于对用户输入的三位数进行翻转。裁判测试程序样例:importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){......
  • 三大硬核方式揭秘:Java如何与底层硬件和工业设备轻松通信!
    大家好,我是V哥,程序员聊天真是三句不到离不开技术啊,这不前两天跟一个哥们吃饭,他是我好多年前的学员了,一直保持着联系,现在都李总了,在做工业互联网相关的项目,真是只要Java学得好,能干一辈子,卷死的是那些半吊子。感谢李总给我分享了工业互联网项目的事情,收获很多,今天的内容来聊一......
  • Java计算正方形
    publicclassSquareArea{//声明一个常量,用于表示正方形的边长publicstaticfinaldoubleSIDE_LENGTH=5.0;publicstaticvoidmain(String[]args){//声明一个局部变量来存储计算得到的面积doublearea;//调用calculateArea方法,并将结果赋值给局部......
  • 第十五届蓝桥杯javaA组 砍柴 (两种写法)详解
    参考资料原题链接砍柴-蓝桥云课(lanqiao.cn)区间质数搜索——埃拉托斯特尼筛法和欧拉筛法-CSDN博客思路质数筛+二分+博弈+状态机(只因bushi)$$状态转移方程 dp[i] = !dp[i-p]$$由原始题意可以看出砍树长度限制为小于其长度的质数——暗示你使用质数筛交替砍......
  • java程序
    importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;classStudent{privateintid;privateStringname;privateintage;publicStudent(intid,Stringname,intage){this.id=id;this.name=name;this.age=age;}......
  • .NET 工具库高效生成 PDF 文档
    前言QuestPDF是一个开源.NET库,用于生成PDF文档。使用了C#FluentAPI方式可简化开发、减少错误并提高工作效率。利用它可以轻松生成PDF报告、发票、导出文件等。项目介绍QuestPDF是一个革命性的开源.NET库,它彻底改变了我们生成PDF文档的方式。QuestPDF的核心思想......