java方法传对象参数_Java方法中的参数太多,第2部分:参数对象

java方法传对象参数

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VB语言与测量程序设计之水准网平差程序(任务8-3含代码,完整工程文件见CSDN资源)

一、程序总体设计 二、程序界面设计 对象属性设置 三、程序代码 矩阵计算类代码 文件名:Matrix.cls 操作矩阵的类 Matrix Option Explicit Const eps As Double = 0.00000001 缺省精度 Dim nRo

【数字信号处理】卷积和乘法系列3之傅里叶变换对

关注公号【逆向通信猿】更精彩!!! 声明:底部的小广告标签并不是博主所加!! 傅里叶变换对(Fourier Transform pairs, FTP) 我们考虑的第一个FTP从时间域中的梳状函数开始,这是一个简单地由相同幅度的规则放置的“冲激(spike)”组成的信号。下面的程序在时域中生成这样…

Gradle教程

1.简介 在本课程中,我们将学习Gradle ,它是一个构建工具和一个依赖管理系统,与Maven和Ant非常相似,并且是专门为构建基于Java的项目而设计的。 与Maven和Ant构建系统不同,Gradle不使用XML。 它实际上是基于Groovy构建…

【定时同步系列6】Gardener误差检测算法原理

关注公号【逆向通信猿】更精彩!!! 引言 离散时间符号定时同步方法 如下图所示为比较常用的一种符号定时同步的离散时间方法,通常由三个基本单元组成离散时间锁相环,分别为:定时误差检测器(TED)、环路滤波器和插值控制。其中,插值器和TED作用相当于鉴相器,插值控制相…

glassfish_RIP GlassFish –感谢所有的鱼。

glassfish我们都听说过。 昨天,JavaEE和GlassFish的官方路线图更新已发布 。 从标题开始,整个帖子基本上是关于一件事的:今天我们知道的GlassFish Server已从完整的产品转为玩具产品。 从太阳到Oracle的漫长道路 从一开始,GlassF…

【定时同步系列7】位(符号)定时同步之模1插值控制和递归插值控制原理

关注公号【逆向通信猿】更精彩!!! 引言 本节主要讨论符号定时同步结构中的插值控制模块,如下图所示,插值控制模块的目的是为内插器提供第 k k k个基点索引 m ( k ) m(k)

活性GWT

介绍 在过去的4到5年中,反应式编程的普及程度得到了极大的提高。 这可以告诉我们,反应性应用程序的用例现在比以往任何时候都有效。 后端系统上的压力增加了,因此需要用最少的资源来处理这种压力。 响应式编程被认为是在减少资源消耗的同时提…

【数字信号处理】卷积和乘法系列3之测不准原理

关注公号【逆向通信猿】更精彩!!! 声明:底部的小广告标签并不是博主所加!! Heisenberg测不准原理 信息在时域中的扩展(尖峰之间的距离)与其在频域中的对应扩展之间的这种关系是Heisenberg不确定性原理的一个例子。时域中的扩展(方差)乘以频域中的扩展具有不能被突破的…

【数字信号处理】卷积和乘法系列3之傅里叶变换对II

关注公号【逆向通信猿】更精彩!!! 声明:底部的小广告标签并不是博主所加!! 采样 傅里叶变换对(FT)很重要的原因是,如果有一个连续时间 (CT) 信号,则可以通过将信号乘以梳状函数来对其进行采样,产生的样本将只是尖峰处的值。采样过程产生离散时间 (DT) 信号,因为采…

使用密钥加密码加密_创建基于密码的加密密钥

使用密钥加密码加密本文讨论了创建基于密码的加密PBE密钥。 首先提醒您以前的要点–通常,在实际操作中,应将PBE密钥用作主密钥,该主密钥仅用于解锁工作密钥。 这具有三个主要优点: 您可以有多个密码,例如&#xff0c…

【定时同步系列8】QPSK基带调制+Gardener定时误差检测+解调误码率曲线之MATLAB并行仿真姊妹篇一

结果预览 误码率曲线 关于反馈型定时同步技术的原理已经陆陆续续讨论了好久了,涉及的各个细节内容较多,且不容易理解,整个流程框图如下所示: 符号定时同步的离散时间方法(异步) 其中, interpolator模块在博客: 【定时同步系列5】Farrow内插器结构原理和MATLAB实现 TED模…

【定时同步系列9】QPSK基带调制+Gardener定时误差检测+解调误码率曲线之MATLAB并行仿真姊妹篇二

关注公号【逆向通信猿】更精彩!!! 上一篇主要对Gardener定时算法进行了MATLAB仿真,其中插值控制字 W ( n ) W(n) W(n)作为环路滤波器的输出,采用迭代的方式进行更新,这也是《数字调制解调技术的MATLAB与FPGA实现》书中代码所采用的的方法! 对于这一点,此次采用另一种…

VS下一种很好的远线程注入的dll调试方法

一、Detorus-master的编译 下载源代码 https://github.com/microsoft/detours 用管理员身份启动 x64 Native Tools Command Prompt for VS 2017 或 x86 Native Tools Command Prompt for VS 2017 用cd命令进入到Detours-master目录下,分别运行以下命令: call "D:\Pr…

eclipse 隐藏项目_前5个有用的隐藏Eclipse功能

eclipse 隐藏项目Eclipse是野兽。 仅凭其力量才能超越其神秘感的设备。 有人将其称为连续体跨功能器 。 其他人则称它为透湿器 。 是的,它是如此之大,需要花费数年才能掌握。 然后,您的经理出现并告诉您:我们正在使用NetBeans。 …

vs2017+qt5.12 未将对象应用设置到对象的实例问题 -解决方法

环境:Win7 VS2017 Qt5.12 使用VS2017的 Qt VS Tools 打开Qt Example下的pro文件时出现如下错误提示: 在这里插入图片描述 查看.qmake.stash 文件如下: 在这里插入图片描述 QMAKE_CXX.QMAKE_MSC_VER 1200 这个配置是问题的根源 经过一天的艰…

使用Spring Security和OAuth 2.0保护Spring微服务架构

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 每个开发人员都希望能够更快,更有效地进行构建以支持规模。 使用Spring构…

Matlab库函数firrcos、rcosfir、rcosine和rcosdesign区别之根升余弦滤波器系数推导详解

一、根升余弦(Square root raised cosine)滤波器系数求解推导 h ( t ) = 4 R cos ⁡ ( ( 1 + R ) π t / T ) + sin

一种使用setdll+HOOK钩子技术+dll为MFC程序ProtocalTool等老旧程序打补丁的思路(含源码)

一、引言 由于工作原因,需要使用一个很老旧的软件,没有源代码,该软件在XP系统下运行正常,但是需要登录,且在win10系统下使用时IP控件运行不正常,只能输入每个数字只能输入2位数,还有一些其他问题,比如给软件添加一些编辑框,或者对软件进行 下面简单梳理一下解决这些…

访存优化_Hibernate事实:多级访存

访存优化在多个级别上检索根实体及其子关联是很常见的。 在我们的示例中,我们需要使用其树,分支和叶子加载森林,并且我们将尝试查看Hibernate在三种集合类型上的表现:集合,索引列表和包。 这是我们的类层次结构的样子…

基于ARM的字符串拷贝实验(嵌入式系统)

基于ARM的字符串拷贝实验 一,实验目的 1.掌握ARM汇编指令LDR、STR和B等的使用方法,完成较为复杂的存储区访问和程序分支,学会使用条件码。 2.掌握完整的ARM汇编程序结构,具备初步的程序编写能力。 3.掌握ADS1.2集成开发环境的工程建立、编译参数设置、程序编译和调试等…