我认为构造函数和方法中冗长的参数列表是Java开发中的另一个“ 危险信号 ”,就逻辑和功能而言,它们不一定是“错误的”,但通常暗示当前或将来出现错误的可能性很高。 在一小部分帖子中,我介绍了一些可用于减少方法或构造函数的参数数量,或至少使冗长的参数列表更易读且更不易出错的方法。 每种方法都有其自己的优点和缺点。 这篇文章开始该系列文章,重点是通过使用自定义类型提高长方法/构造函数参数列表的可读性和安全性。

冗长的方法和构造方法参数列表有几个缺点。 大量参数可能很乏味,并且难以调用代码使用。 较长的参数列表也可能导致调用中参数的无意切换。 在某些情况下,可能很难找到这些错误。 幸运的是,大多数方法不必处理冗长的参数列表的另一个缺点: JVM通过编译时错误 将参数的数量限制为一个方法 。

自定义类型的使用是一种不减少方法或构造函数的参数数量,但确实使这些较长的参数列表更易读且不太可能以错误的顺序提供的方法。 这些自定义类型可以实现为数据传输对象 (DTO), JavaBeans , 值对象 , 引用对象或任何其他自定义类型(在Java中,通常是类或枚举 )。

这是一个人为设计的方法示例,该方法接受多个参数,其中许多参数为String类型,许多参数为boolean类型。

/*** Instantiate a Person object.* * @param lastName* @param firstName* @param middleName* @param salutation* @param suffix* @param streetAddress* @param city* @param state* @param isFemale* @param isEmployed* @param isHomeOwner* @return */public Person createPerson(final String lastName,final String firstName,final String middleName,final String salutation,final String suffix,final String streetAddress,final String city,final String state,final boolean isFemale,final boolean isEmployed,final boolean isHomeOwner){// implementation goes here}

容易意外地切换它们并以错误的顺序传递它们。 尽管我通常希望减少参数,但是可以通过更改参数列表中的类型来进行一些改进。 接下来的代码清单显示了这些自定义类型的一些示例,这些示例可用于名称,地址,城市和布尔参数。

可以将三个name参数分别更改为Name的自定义类型,而不是String 。 接下来定义该Name类型。

名称.java

package dustin.examples;/*** Name representation.* * @author Dustin*/
public final class Name
{private final String name;public Name(final String newName){this.name = newName;}public String getName(){return this.name;}@Overridepublic String toString(){return this.name;}
}

称呼和后缀String类型也可以替换为自定义类型,如以下两个代码清单所示。

Salutation.java

package dustin.examples;/*** Salutations for individuals' names.* * @author Dustin*/
public enum Salutation
{DR,MADAM,MISS,MR,MRS,MS,SIR
}

后缀.java

package dustin.examples;/*** Suffix representation.* * @author Dustin*/
public enum Suffix
{III,IV,JR,SR
}

其他参数也可以用自定义类型替换。 接下来的代码清单显示了可以替换boolean以提高可读性的自定义枚举。

Gender.java

package dustin.examples;/*** Gender representation.* * @author Dustin*/
public enum Gender
{FEMALE,MALE
}

EmploymentStatus.java

package dustin.examples;/*** Representation of employment status.* * @author Dustin*/
public enum EmploymentStatus
{EMPLOYED,NOT_EMPLOYED
}

HomeOwnerStatus.java

package dustin.examples;/*** Representation of homeowner status.* * @author Dustin*/
public enum HomeownerStatus
{HOME_OWNER,RENTER
}

也可以使用定义的自定义类型来传递此人的地址信息,如以下代码清单所示。

StreetAddress.java

package dustin.examples;/*** Street Address representation.* * @author Dustin*/
public final class StreetAddress
{private final String address;public StreetAddress(final String newStreetAddress){this.address = newStreetAddress;}public String getAddress(){return this.address;}@Overridepublic String toString(){return this.address;}
}

City.java

package dustin.examples;/*** City representation.* * @author Dustin*/
public final class City
{private final String cityName;public City(final String newCityName){this.cityName = newCityName;}public String getCityName(){return this.cityName;}@Overridepublic String toString(){return this.cityName;}
}

State.java

package dustin.examples;/*** Simple representation of a state in the United States.* * @author Dustin*/
public enum State
{AK,AL,AR,AZ,CA,CO,CT,DE,FL,GA,HI,IA,ID,IL,IN,KS,KY,LA,MA,MD,ME,MI,MN,MO,MS,MT,NC,ND,NE,NH,NJ,NM,NV,NY,OH,OK,OR,PA,RI,SC,SD,TN,TX,UT,VA,VT,WA,WI,WV,WY
}

通过实现这些自定义类型,我们原始方法的签名变得更具可读性,并且不太可能意外地以错误的顺序提供参数。 这显示在下一个代码清单中。

public Person createPerson(final Name lastName,final Name firstName,final Name middleName,final Salutation salutation,final Suffix suffix,final StreetAddress address,final City city,final State state,final Gender gender,final EmploymentStatus employment,final HomeownerStatus homeowner){// implementation goes here}

在上面的代码清单中,编译器现在将通过不允许之前的大多数Stringboolean参数意外混合来帮助开发人员。 这三个名称仍然是一个潜在的问题,因为调用方可能会无序提供它们,但是如果我担心的话,我可以为FirstNameLastNameMiddleName编写特定的类型(类)。 相反,我更喜欢使用一个代表全名的新类,并将这三个名称全部用作其属性,但是该方法将成为以后处理Java方法的过多参数的主题。

优势与优势

在给定方法上处理多个参数时编写和使用自定义类型的优点包括代码维护者和使用API​​的开发人员的可读性。 具有多个相同类型的参数,不仅使开发人员可以轻松混合其顺序,还降低了IDE在使用代码完成功能时将适当建议与参数匹配的能力。 正确的命名可以对IDE有所帮助,但是对IDE而言,没有什么比使用这些自定义类型可以完成的静态编译时检查有用的了。 总的来说,我更愿意从运行时转移尽可能多的自动检查到编译时,并且让这些静态定义的自定义类型(而不是通用类型)来完成此任务。

此外,这些自定义类型的存在使将来更容易添加更多详细信息。 例如,将来我可以在不更改接口的情况下,将完整的状态名称或有关状态的其他详细信息添加到该枚举中。 我不可能用一个简单的String来表示状态。

成本与劣势

自定义类型方法最常被引用的缺点之一是额外的实例化和内存使用的开销。 例如, Name类需要实例化Name类本身及其封装的String 。 但是,我认为,这种争论通常是从过早优化的角度出发,而不是合理的衡量性能问题。 在某些情况下,额外的实例化过于昂贵,以至于无法证明增强的可读性和编译时检查,但是许多(也许大多数 )情况可以提供额外的实例化,而其可观察到的影响却可以忽略不计。 我很难相信使用自定义枚举而不是Stringboolean会在大多数情况下引入性能问题。

使用自定义类型而不是内置类型的另一个缺点是编写和测试这些自定义类型需要额外的精力。 但是,如本文中的示例所示,通常存在非常简单的类或枚举,并且不难编写或测试。 有了良好的IDE和良好的脚本语言(例如Groovy),它们特别容易自动编写和测试。

结论

我喜欢使用自定义类型来提高可读性,并将更多的参数类型检查负担转移到编译器上。 我没有更多地使用这种方法来提高具有非常长的参数列表的方法和构造函数的可读性的最大原因是,它本身并没有减少参数的数量。 它使长列表更易于阅读和使用,但调用方仍然必须编写笨拙的客户端代码才能调用该方法或构造函数。 因此,在改进接受一长串参数的方法时,我经常使用除自定义类型以外的技术。 这些其他技术将在以后的文章中探讨。

参考: Java方法中的参数过多,第1部分:来自JCG合作伙伴 Dustin Marx的“ 实际事件的启发”博客中的自定义类型 。

翻译自: https://www.javacodegeeks.com/2013/10/too-many-parameters-in-java-methods-part-1-custom-types.html

Java方法中的参数太多,第1部分:自定义类型相关推荐

  1. Java方法中的参数太多,第8部分:工具

    在我的系列文章的前七篇文章中,有关处理Java方法中期望的参数过多的内容集中在减少方法或构造函数期望的参数数量的替代方法上. 在本系列的第八篇文章中,我将介绍一些工具,这些工具可帮助您确定可能存在过多 ...

  2. Java方法中的参数太多,第4部分:重载

    期望将过多的参数传递给Java方法的问题之一是,该方法的客户端很难确定它们是否以适当的顺序传递了适当的值. 在以前的文章中,我描述了如何使用自定义类型 , 参数对象和构建器来解决此问题. 解决此问题的 ...

  3. Java方法中的参数太多,第5部分:方法命名

    在上一篇文章 (有关处理Java方法中过多参数的系列文章的 第4部分 )中,我将方法重载视为一种向客户提供需要较少参数的方法版本或构造函数的方法. 我描述了该方法的一些缺点,并建议从方法重载中摆脱出来 ...

  4. Java方法中的参数太多,第7部分:可变状态

    在我的系列文章的第七篇中,有关解决Java方法或构造函数中过多参数的问题 ,我着眼于使用状态来减少传递参数的需要. 我等到本系列的第七篇文章来解决这个问题的原因之一是,它是我最不喜欢的减少传递给方法和 ...

  5. Java方法中的参数太多,第6部分:方法返回

    在当前的系列文章中,我正在致力于减少调用Java方法和构造函数所需的参数数量,到目前为止,我一直专注于直接影响参数本身的方法( 自定义类型 , 参数对象 , 构建器模式 , 方法重载和方法命名 ). ...

  6. Java方法中的参数太多,第3部分:构建器模式

    在我的前两篇文章中,我研究了如何通过自定义类型和参数对象减少构造函数或方法调用所需的参数数量. 在本文中,我将讨论如何使用构建器模式来减少构造器所需的参数数量,并讨论该模式如何甚至可以帮助采用过多参数 ...

  7. Java方法中的参数太多,第2部分:参数对象

    在上一篇文章中 ,我研究了与方法和构造函数的长参数列表相关的一些问题. 在那篇文章中,我讨论了用自定义类型替换基元和内置类型以提高可读性和类型安全性. 这种方法使方法或构造函数的众多参数更具可读性,但 ...

  8. java命令行参数工具_Java方法中的参数太多,第8部分:工具

    java命令行参数工具 在我的系列文章的前七篇文章中,有关处理Java方法中期望的参数过多的内容集中在减少方法或构造函数期望的参数数量的替代方法上. 在本系列的第八篇文章中,我将介绍一些工具,这些工具 ...

  9. java中重载 参数顺序_Java方法中的参数太多,第4部分:重载

    java中重载 参数顺序 期望将过多的参数传递给Java方法的问题之一是,该方法的客户端很难确定它们是否以适当的顺序传递了适当的值. 在以前的文章中,我描述了如何使用自定义类型 , 参数对象和构建器来 ...

最新文章

  1. windows连linux工具,Windows连接Linux工具
  2. sublime Package Control 设备
  3. 每天一个linux命令-用户之间切换
  4. 用万字长文聊一聊 Embedding 技术
  5. 聊聊 Java8 以后各个版本的新特性
  6. 清空list_还在为邮箱爆掉而烦恼吗?学会清空你的收件箱
  7. java 分贝_java11教程--jhsdb命令
  8. 冒泡排序、快速排序 java代码实现
  9. 数据库函数..........
  10. ubuntu 16.04 x86_64中arm-none-linux-gnueabi-不起作用时的解决方案
  11. java break与continue_java中的break与continue
  12. QAliber - 介绍一款开源的GUI自动化测试工具
  13. Tomcat 修改端口
  14. 编写一个生成器函数,能够生成斐波那契数列
  15. ElasticJob‐Lite:作业监听器
  16. 基于Web的教学网站前端开发设计 报告+任务书+html源码
  17. 鸿蒙大陆v2.8正式版,鸿蒙大陆2.2正式版附隐藏密码
  18. 基于语法分析的公式分析器设计
  19. SSM SpringBoot vue办公自动化计划管理系统
  20. ThinkPad E40取消FN功能键设置

热门文章

  1. php无限极菜单,无限极菜单的实现
  2. java的BASE64Encoder,BASE64Decoder加密与解密
  3. Spring MVC开发环境搭建
  4. apache kafka_Apache Kafka消费者再平衡
  5. jsoup爬虫教程技巧_Jsoup V的幕后秘密:优化的技巧和窍门
  6. jug java_架构大型企业Java项目–我的虚拟JUG会话
  7. java多线程 异常处理_Java8多线程ForkJoinPool:处理异常
  8. java常见性能优化_十大最常见的Java性能问题
  9. javafx隐藏_JavaFX技巧14:StackPane子项-隐藏但不消失
  10. Java和JavaScript之间的区别