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

通常,使“垃圾箱”对象耦合不相关的参数通常不是一个好主意,这些参数之间的唯一关系是它们需要传递给相同的方法或构造函数。 但是,当将相关参数作为高度内聚的对象的一部分传递给构造函数或方法时,称为Introduce Parameter Object的重构是一个不错的解决方案。 重构的用法被描述为 “自然组合在一起的参数组”。 我将在这篇文章中演示这种重构。

为了演示Introduce Parameter Object重构的效用,让我们首先来看最后一篇文章中的示例,该示例在方法调用中使用了许多Stringboolean参数。

/*** 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}

正如我在上一篇文章中所讨论的那样,这种方法对于调用者来说是乏味的,使得以错误的顺序传递参数变得非常容易,而类型安全性却很少,并且会降低代码的可读性。 幸运的是,此示例中的参数为应用Introduce Parameter Object重构提供了一些很好的机会。 “名称”参数(包括称呼和后缀)可以包含在单个全名类中。 地址参数(街道地址,城市和州)可以位于单个地址对象中。 其他参数可能不太容易分组为具有高内聚力的单个类。

使用“引入参数对象”重构的建议应用程序,由于减少了参数数量,因此前面显示的方法调用更加简单。 这显示在下一个代码清单中。

public Person createPerson(final FullName fullName,final Address address,final boolean isFemale,final boolean isEmployed,final boolean isHomeOwner){return new Person();}

上面的示例现在只有五个参数,并且更易于阅读,并且更易于客户端使用。 从键入的角度来看,它也是更安全的,因为在这种情况下几乎不可能将名称字符串与地址字符串混淆。 不幸的是,这三个布尔参数仍然有点造成潜在的混乱和云可读性。 接下来的代码清单显示FullNameAddress类的潜在实现。

FullName.java(简单)

package dustin.examples;/*** Full name of a person.* * @author Dustin*/
public final class FullName
{private final String lastName;private final String firstName;private final String middleName;private final String salutation;private final String suffix;public FullName(final String newLastName,final String newFirstName,final String newMiddleName,final String newSalutation,final String newSuffix){this.lastName = newLastName;this.firstName = newFirstName;this.middleName = newMiddleName;this.salutation = newSalutation;this.suffix = newSuffix;}public String getLastName(){return this.lastName;}public String getFirstName(){return this.firstName;}public String getMiddleName(){return this.middleName;}public String getSalutation(){return this.salutation;}public String getSuffix(){return this.suffix;}@Overridepublic String toString(){return  this.salutation + " " + this.firstName + " " + this.middleName+ this.lastName + ", " + this.suffix;}
}

Address.java(简单)

package dustin.examples;/*** Representation of a United States address.* * @author Dustin*/
public final class Address
{private final String streetAddress;private final String city;private final String state;public Address(final String newStreetAddress, final String newCity, final String newState){this.streetAddress = newStreetAddress;this.city = newCity;this.state = newState;}public String getStreetAddress(){return this.streetAddress;}public String getCity(){return this.city;}public String getState(){return this.state;}@Overridepublic String toString(){return this.streetAddress + ", " + this.city + ", " + this.state;}
}

尽管代码得到了改进,但是仍有一些问题可以改进。 特别是,具有太多参数的原始方法仍然具有三个boolean参数,可以很容易地将它们相互混淆。 尽管该方法的String参数被分解为两个新类,但这两个新类仍分别由一堆String组成。 在这些情况下,可能需要使用自定义类型来补充“ 介绍参数对象”重构。 使用我在上一篇文章中显示的自定义类型,带有太多参数的方法现在看起来像下一个代码清单中所示。

public Person createPerson(final FullName fullName,final Address address,final Gender gender,final EmploymentStatus employment,final HomeownerStatus homeownerStatus){// implementation goes here}

该方法现在具有较少的参数,并且确实具有不同类型的参数。 现在,IDE和Java编译器对于确保客户端正确使用此接口特别有用。 将自定义类型(写在最后一篇文章中)应用于FullNameAddress类会导致这些类的下两个新代码清单。

FullName.java(自定义类型)

package dustin.examples;/*** Full name of a person.* * @author Dustin*/
public final class FullName
{private final Name lastName;private final Name firstName;private final Name middleName;private final Salutation salutation;private final Suffix suffix;public FullName(final Name newLastName,final Name newFirstName,final Name newMiddleName,final Salutation newSalutation,final Suffix newSuffix){this.lastName = newLastName;this.firstName = newFirstName;this.middleName = newMiddleName;this.salutation = newSalutation;this.suffix = newSuffix;}public Name getLastName(){return this.lastName;}public Name getFirstName(){return this.firstName;}public Name getMiddleName(){return this.middleName;}public Salutation getSalutation(){return this.salutation;}public Suffix getSuffix(){return this.suffix;}@Overridepublic String toString(){return  this.salutation + " " + this.firstName + " " + this.middleName+ this.lastName + ", " + this.suffix;}
}

Address.java(自定义类型)

package dustin.examples;/*** Representation of a United States address.* * @author Dustin*/
public final class Address
{private final StreetAddress streetAddress;private final City city;private final State state;public Address(final StreetAddress newStreetAddress, final City newCity, final State newState){this.streetAddress = newStreetAddress;this.city = newCity;this.state = newState;}public StreetAddress getStreetAddress(){return this.streetAddress;}public City getCity(){return this.city;}public State getState(){return this.state;}@Overridepublic String toString(){return this.streetAddress + ", " + this.city + ", " + this.state;}
}

到目前为止,我所有的示例都是独立的public类。 我经常发现,如果我只需要一个参数对象来在同一包中的方法和构造函数之间传递信息,那么使这些参数对象类的package作用域很有用。 在某些情况下,嵌套类也可以用于这些参数对象。

优势与优势

参数对象最明显的好处是减少了传递给方法或构造函数的参数数量。 相关参数的这种封装使快速确定要传递给方法或构造函数的类型变得更加容易。 开发人员更容易理解较少的参数。

参数对象具有与自定义类型相同的优点之一:可以为方便功能向参数对象添加其他行为和特征。 例如,拥有一个Address类而不是一堆String类型可以使人们验证地址。

成本与劣势

参数对象的主要缺点是设计,实现和测试类需要一些额外的工作。 但是,这些工具非常易于编写和测试,而现代工具(如IDE和脚本语言)使这些任务中最平凡和繁琐的部分的自动化更加容易。 反对这种方法的一个更小的论点是它可以被滥用。 如果开发人员开始将不相关的参数捆绑到一个类中只是为了减少参数的数量,那并不一定会解决这种情况。 这种方法的确确实减少了参数的数量,但是没有实现提高可读性的最终目标,并且可以说这种方法的可读性更低。

结论

参数对象提供了一种很好的干净方法,可以适当地封装相关参数,以减少方法或构造函数的总参数数量。 它们易于实现,并且可以显着增强传递给方法和构造函数调用的可读性和类型安全性参数。 可以通过使用自定义类型进一步增强参数对象,如我之前的文章中所述。

参考: Java方法中的参数太多,第2部分:来自JCG合作伙伴 Dustin Marx的“ Inspired by Actual Events”博客中的Parameters对象 。

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

Java方法中的参数太多,第2部分:参数对象相关推荐

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

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

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

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

  3. Java方法中的参数太多,第1部分:自定义类型

    我认为构造函数和方法中冗长的参数列表是Java开发中的另一个" 危险信号 ",就逻辑和功能而言,它们不一定是"错误的",但通常暗示当前或将来出现错误的可能性很高 ...

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

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

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

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

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

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

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

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

  8. JAVA方法中的参数用final来修饰的原因

    JAVA方法中的参数用final来修饰的原因 很多人都说在JAVA中用final来修饰方法参数的原因是防止方法参数在调用时被篡改,其实也就是这个原因,但理解起来可能会有歧义,有的人认为是调用语句的地方 ...

  9. Java方法中的局部类和匿名类

    1.局部类   在一个方法中定义的类称为方法中的内部类,或者叫做局部类(local class). 示例:Ex5_TestInnerInMethod.java方法中的内部类 public class ...

最新文章

  1. 鸿蒙系统的升级名单,首批升级鸿蒙系统的名单确认,华为安卓系统将成为过去式!...
  2. python编程16章教程_Python学习笔记__16.2章 TCP编程
  3. 笔记本暗屏维修多少钱_电视机维修|维修电视机多少钱?电视机黑屏
  4. UVA1601The Morning after Halloween 单向加双向bfs
  5. 关于 Orbeon form PE 版本使用 JavaScript Embedding API 的一个例子
  6. LSI系新军搅局,PCIe固态盘混战?
  7. 前端学习(615):变量
  8. pip 安装网络超时解决方案
  9. mac下flink集群安装
  10. mysql内外三种连接_mysql之内连接,外连接(左连接,右连接),union,union all的区别...
  11. C#基于Linq和反射实现数据持久化框架Xml4DB
  12. CCCC-GPLT L2-019. 悄悄关注 团体程序设计天梯赛
  13. C++ 动态连接库使用
  14. python 2.7安装pandas失败
  15. 深度学习面试题之CNN
  16. Java-图片处理 Gif转Jpg
  17. Delphi-日期时间函数
  18. 国家代码查询(Country codes)
  19. Codeforces 311D Interval Cubing 数学 + 线段树 (看题解)
  20. #VMware#ESXI ESXI虚拟机安装

热门文章

  1. 复制vmware overLay网络无法ping通 ping www.baidu.com可以
  2. CentOS - 修改主机名教程(将 localhost.localdomain 改成其它名字)
  3. arm linux串口控制led,通信程序设计 - Linux下ARM和单片机的串口通信设计
  4. char类型和Unicode编码
  5. java泛型程序设计——注意擦除后的冲突
  6. 创建react应用程序_使用SpringWebFlux的React式Web应用程序
  7. 重置线程中断状态_记住要重置线程上下文类加载器
  8. jboss7.0.2_红帽JBoss企业应用平台7.0 ALPHA发布了!
  9. java学习里程碑_记录您的里程和社区运行情况:Java EE 7真实体验
  10. java7和java8切换_仍不切换到Java 8的6个理由