这条其实没什么好说的,每个程序员都遇到过参数大爆炸的情况,面对大量的可选参数,怎么办?
直接上例子。考虑用一个类表示食品外包装的营养成分标签。这些标签中的有几个域是必须的:每份的分量,每罐的含量以及每份的卡路里,还有超过20个的可选域:总脂肪量,饱和脂肪量,转化脂肪,胆固醇等等,大多数产品在某几个域中都会有非零的值。
Public class NutritionFacts { private final int servingSize;//ml required private final int serings;// per container required private final int calories;//optional private final int fat;//g optional private final int sodium;//mg optional private final int carbonhydrate;//g optional public NutritionFacts(int servingSize,int serings){ this(servingSize,servings,0); } public NutritionFacts(int servingSize,int serings,int calories){ this(servingSize,serings,calories,0); } public NutritionFacts(int servingSize,int serings,int calories,fat){ this(servingSize,serings,calories,fat,0); } public NutritionFacts(int servingSize,int serings,int calories,fat,sodium){ this(servingSize,serings,calories,fat,sodium,0); } public NutritionFacts(int servingSize,int serings,int calories,fat,sodium,carbonhydrate){ this.servingSize = servingSize; this.serings = servings; this.calories = calories; this.fat = fat; this.sodium = sodium; this.carbonhydrate = carbonhydrate; } }
这种方式是最常见的,缺点也是显而易见的,代码的可读性非常差,而且非常容易出错。
另外一种常见的方式就是JavaBean的方式,先创建实例,再通过set方法初始化,这种方式的缺点也很明显,破坏了创建对象操作的原子性,在构造过程中对象可能处于不一致的状态。
好了,来看一个两全其美的办法吧:
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 carbonhydrate; public static class Builder { private final int servingSize; private final int servings; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbonhydrate = 0; public Builder(int servingSize,int serving){ this.servingSize = servingSize; this.servings = serving; } public Builder calories(int val){ this.calories = val; return this; } public Builder fat(int val){ this.fat = val; return this; } public Builder carbonhyate(int val){ this.carbonhydrate = val; return this; } public Builder sodium(int val){ this.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; carbonhydrate = builder.carbonhydrate; } public static void main(String[] args) { NutritionFacts cocacola = new NutritionFacts.Builder(240,80).calories(100).sodium(35).carbonhyate(27).build(); } }
怎么样,是不是两个缺点都避免了,安全性和可读性都很好,当然Builder模式也有它自身的不足,创建构建器会产生一定的开销,对性能要求非常严格的情况下就不一定是最完美的解决方案了。
相关推荐
第2章着重讲解了构造器模式,这是一种创建型设计模式,它关注的是对象的初始化过程。下面将详细阐述构造器模式的相关知识点,并结合提供的文件名来推测可能的学习内容。 首先,让我们理解构造器模式的基本概念。在...
在构建词法分析器时,我们需要考虑以下关键概念和步骤: 1. **词法规则**:定义每个标记的模式,例如,关键字“if”,数字模式,标识符等。 2. **状态转换**:通过DFA,根据当前读取的字符决定词法分析器应进入的下...
在 Laravel 中,开发者可以利用其丰富的工具和库来提高开发效率,而 "Former" 正是这样一个专为 Laravel 设计的表单构造器。 Former 是一款强大的第三方库,它的主要目标是帮助 Laravel 开发者快速、方便地创建和...
**遇到多个构造器参数时的考虑**: - **重叠构造器模式**:这种模式下,每个构造器提供比前一个多一个参数,但是这种模式会导致构造器过多,增加复杂度。 - **JavaBeans模式**:虽然使用无参构造器并结合setter方法...
解释器的构造涉及到多个关键步骤,包括词法分析、语法分析、语义分析和代码生成。下面我们将详细探讨这些步骤以及它们在实验中的重要性。 1. **词法分析**:这是解释器的第一步,它将源代码分解成一系列称为“标记...
语法分析器是编译器的第二阶段,其主要任务是从词法分析器(也称为扫描器)生成的标记流中构建抽象语法树(AST)。这个过程依据的是源代码的语法规则,通常由一套形式化的文法定义,如上下文无关文法(Context-Free ...
词法分析器的构造是编译器设计与实现的重要组成部分,涉及到了状态转移、正则表达式等多个概念。 1. **词法分析器的作用** 词法分析器的作用是将源代码中的字符流转化为符号流,这个过程包括识别关键字、标识符、...
- 可以有多个构造器,通过不同的参数实现不同方式的初始化。 7. **this关键字**: - `this`关键字引用当前对象实例,常用于区分成员变量和局部变量,以及在构造器中调用其他构造器。 8. **final关键字**: - `...
� A ndroid 在设计初期就考虑了与现其有业务的融合,改变以往从计算机为主改成从手机使用为导向。新 生应用如:G oogle 地图及其衍生应用、 GMail 、 GTalk 等。 � GPS 卫星导航功能,手机照相, MP3 ,蓝芽等均...
#### 第二章:Windows编程的基础知识 - **窗口**(第55页) - Windows应用程序的核心组成部分之一。 - **Windows的消息系统** - **消息驱动(事件驱动)** - 应用程序响应用户的输入和其他事件。 - **事件队列...
在"数据挖掘实战第2章用scikit-learn估计器分类"中,我们将会深入探讨如何使用scikit-learn进行有效的分类任务。 首先,分类是数据挖掘中的核心任务之一,它旨在根据输入特征将数据点分配到预定义的类别中。scikit-...
### Protege构建本体知识点详解 #### 一、概述 Protege是一款广泛使用的开源本体编辑工具,它能够帮助用户构建、管理和编辑基于OWL(Web Ontology Language)的本体。通过Protege,我们可以定义实体之间的关系,...
8-4-10 在ModelMaker中改进控件 8-4-11 在ModelMaker中继续编辑你的代码 8-4-12 重载构造器Create 8-4-13 实现Create,非用户节代码 8-4-14 即时代码生成 8-4-15 文档化你的控件8-4-16 创建一个帮助文件 8-4-17 在图...
- "this"在构造器中可以用来调用其他构造器,但必须作为其第一条语句。 5. **this在实际编程中的应用**: - 在方法重载中,"this"可以帮助避免混淆,确保正确调用实例方法。 - 在构建复杂对象时,"this"可以简化...
第二版的《Java面向对象程序设计》课件旨在深入浅出地介绍这一关键概念,帮助学习者掌握Java语言的基础以及面向对象编程的核心思想。下面将详细阐述Java面向对象编程的基本概念、特性及其在实际开发中的应用。 1. ...
状态观测器的研究还包括其维数、结构条件、代数等价等多个方面,这些都是保证系统性能和稳定性的关键因素。通过深入学习和掌握这些理论,工程师能够更好地设计和实现复杂控制系统的状态反馈控制。
本项目“编译原理及实践手工构造词法分析器”聚焦于手动构建词法分析器这一核心技能,旨在帮助学习者深入理解编译器的工作机制,并通过实践提升对这一领域的掌握。 词法分析器,也被称为扫描器或词法分析程序,是...
这个文法定义了一个Number由一个或多个Digit组成,而Digit只能是0或1。类似地,可以为十进制数字建立一个文法。 接下来是语义分析阶段,这个阶段关注的是程序的意义而非结构。在“二---十进制”转换中,语义分析器...