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

在上一篇文章 (有关处理Java方法中过多参数的系列文章的 第4部分 )中,我将方法重载视为一种向客户提供需要较少参数的方法版本或构造函数的方法。 我描述了该方法的一些缺点,并建议从方法重载中摆脱出来以使用不同名称的方法至少可以部分解决这些缺点。 在本文中,我将更深入地探讨如何使用仔细的方法命名(包括构造方法)来删除冗长的参数列表并避免方法重载的某些问题。

从减少方法和构造函数调用中所需的参数数量的角度来看,与方法重载相关的一些最重要的问题围绕着对大量参数可以重载相同方法名多少次的限制,尤其是在某些情况下的参数共享相同的数据类型。 例如,如果我有一个具有三个String属性的类,并且想编写三个构造函数以分别仅接受这些属性之一,那么我真的不能通过方法重载来做到这一点。 如果我尝试过,则必须将接受单个String的构造函数用于三个属性之一,并且只有Javadoc注释才能解释单参数构造函数设置的三个属性中的哪个。 摆脱对所有方法和构造方法使用相同名称的限制,可以使代码在预期和假定参数方面更具表现力。

下面的代码清单包含各种方法的一些示例,这些方法要求一个独立的类(不是Person类)提供Person的实例(在我以前的文章中引用了太多的Java参数,该类引用了该类)。 这些方法的名称很长,描述了有关参数预期的内容。 这意味着Javadoc注释中需要描述的内容更少,客户端更容易理解方法的调用,并且与方法重载相比,可以支持更多参数的可能性和排列。

命名方法的示例以描述其功能

public Person createPersonWithFirstAndLastNameOnly(final String firstName, final String lastName){// implementation goes here ...}public Person createEmployedHomeOwningFemale(final FullName name, final Address address){// implementation goes here ...}public Person createEmployedHomeOwningMale(final FullName name, final Address address){// implementation goes here ...}public Person createUnemployedHomeOwningFemale(final FullName name, final Address address){// implementation goes here ...}public Person createEmployedRentingMale(final FullName name, final Address address){// implementation goes here ...}

上面代码中显示的较长的方法名称具有描述性,可为客户端提供一个良好的起点,让他们知道要提供哪些参数。 当然,我可以编写更多类似上述方法的方法来介绍参数的各种排列,但是我列出的小集合可以说明这一点。 注意,在这些代码示例中,我还使用了参数对象 (在我的参数对象文章中定义的FullNameAddress )来进一步减少参数的数量。

我上面的代码示例演示了为实例方法提供不同的描述性名称,以暗示要传递的参数,甚至在某些情况下还暗示不需要提供哪些参数,因为它们隐含在方法名称中。 Java的新手可能会认为此方法不能与对象实例化/构造一起使用,因为Java类构造函数必须使用与该类相同的名称来命名。 这意味着只能基于方法签名重载构造函数。 幸运的是, Josh Bloch在Effective Java的两个版本的第一篇中谈到了这一问题。 正如Bloch在此处所述,我们可以采用静态初始化工厂方法来提供类的实例。 Bloch在第1项中引用的好处之一是能够按我们认为合适的方式命名这些方法。

下一个代码清单演示了这些静态初始化工厂的功能。 当我实现这些时,我喜欢实现仅由静态初始化工厂调用的一个或很少数量的private构造函数(无法通过外部类实例化)。 这使我可以将构造函数的方法签名留给潜在的不足,因为仅我的类必须使用它,而其他人使用的静态初始化工厂更易于使用,并且隐藏了许多参数构造函数的丑陋之处。 更具体地说,如果构造函数对可选参数采用null,则可以编写各种静态初始化工厂,以便我的客户端不需要传递null,但我的工厂方法可以将null传递给构造函数。 简而言之,静态初始化工厂方法使我能够为客户端提供更简洁,更愉悦的界面,并在类的内部隐藏丑陋之处。 由于无法用解释性细节给它们命名,因此我不能轻易地直接为它提供多个构造函数。 这些静态初始化方法的另一个优点是,如果需要,我可以让它们接受“原始”类型并将其内置到自定义类型和参数对象中。 所有这些情况在下一个代码清单中显示。

静态初始化工厂展示

/*** Parameterized constructor can be private because only my internal builder* needs to call me to provide an instance to clients.* * @param newName Name of this person.* @param newAddress Address of this person.* @param newGender Gender of this person.* @param newEmployment Employment status of this person.* @param newHomeOwner Home ownership status of this person.*/private Person(final FullName newName, final Address newAddress,final Gender newGender, final EmploymentStatus newEmployment,final HomeownerStatus newHomeOwner){this.name = newName;this.address = newAddress;this.gender = newGender;this.employment = newEmployment;this.homeOwnerStatus = newHomeOwner;}public static Person createInstanceWithNameAndAddressOnly(final FullName newName, final Address newAddress){return new Person(newName, newAddress, null, null, null);}public static Person createEmployedHomeOwningFemale(final FullName newName, final Address newAddress){return new Person(newName, newAddress, Gender.FEMALE, EmploymentStatus.EMPLOYED, HomeownerStatus.HOME_OWNER);}public static Person createEmployedHomeowningMale(final FullName newName, final Address newAddress){return new Person(newName, newAddress, Gender.MALE, EmploymentStatus.EMPLOYED, HomeownerStatus.HOME_OWNER);}public static Person createUnemployedMaleRenter(final FullName newName, final Address newAddress){return new Person(newName, newAddress, Gender.MALE, EmploymentStatus.NOT_EMPLOYED, HomeownerStatus.RENTER);}public static Person createPersonWithFirstNameLastNameAndAddress(final Name newFirstName, final Name newLastName, final Address newAddress){return new Person(new FullName.FullNameBuilder(newLastName, newFirstName).createFullName(),newAddress, null, null, null);}public static Person createPersonWithFirstNameLastNameAndAddress(final String newFirstName, final String newLastName, final Address newAddress){return new Person(new FullName.FullNameBuilder(new Name(newLastName), new Name(newFirstName)).createFullName(),newAddress, null, null, null);}

如以上示例所示,这些方法的客户可以使用可读性强的方法,而不必担心提供大量参数。 前面的代码清单中的最后两个方法是将方法重载与静态初始化工厂方法结合在一起的示例。

优势与优势

使用适当命名的方法(在这些方法的名称中包含有关预期参数和隐含参数的信息)会带来一些优于简单方法/构造函数重载的优点。 由于可以根据每种方法的预期和假设自定义方法的名称,因此调用代码的意图更加明确。 如上面的示例所示,这些方法可能意味着不需要显式提供哪些参数,因为它们被假定为该方法的一部分(并且意图是通过方法的名称而不是通过Javadoc进行通信的)。

我在这里没有明确地关注它,但是与简单的方法重载相比,精心选择的方法名称的另一个优点是能够在方法名称中包含单元或其他上下文信息。 例如,我可以提供setWholeLengthInMeters(int)setFractionalLengthInFeet(double)方法,而不是使用接受intdouble setLength()方法。

成本与劣势

使用名称不同的实例方法和静态初始化工厂方法肯定比方法重载提供了一些优势,但是不幸的是,从参数减少的角度来看,仍然具有方法重载的一些缺点。 不同名称的方法与重载方法共享的一个缺点是可能必须编写许多方法来支持可能使用的参数的各种组合和排列。 如果在以上示例中仅针对性别,房主身份和就业身份的每种组合编写了一种方法,则将需要八个方法(第2到第3次幂)。 如果任何一个单独的参数可以具有2种以上的可能性,则命名方法的不同组合的数量仅用于处理该增加的不同可能性。 当然,没有有限可能性的参数不能为每个可能的值编写方法,因此必须传入而不是假定。

尽管描述性很强的方法名称很容易阅读,但潜在的名称过多可能会降低总体可读性,因为客户端在调用类时必须经过一长串方法。 同样,某些人可能不喜欢长的方法名称以及他们在屏幕上占用大量空间。 我个人并不介意长名称,因为我认为它们提供的可读性值得在屏幕上添加其他文本。 IDE和代码完成功能意味着很少有人再输入这些名称,并且开发人员使用了很多监视器,这使得长方法名称的问题不再那么麻烦。

结论

方法的名称可用于向客户传达重要意义。 在我们努力澄清要传递给特定方法的参数(包括减少参数数量)的情况下,适当地命名方法可以隐含默认设置,从而无需提供参数,并且可以解释参数的顺序和其他特征。其他确实需要应用的参数。

参考: Java方法中的参数太多,第5部分: JCG合作伙伴 Dustin Marx在《 实际事件的启发》博客上的方法命名 。

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

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

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

相关文章

微信小程序搭配小白接口,自己没有服务器也能开发哦

这里将重点介绍,在自己没有服务器的情况下,如何在微信小程序里直接调用小白接口。 前提 假设你已经开通微信小程序,如果还没有,可前往微信公众平台开通:https://mp.weixin.qq.com 假设你已经开通小白接口&#xff0c…

LeetCode:34. 在排序数组中查找元素的第一个和最后一个位置

1、题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums [5,7,7,8,8,10], targ…

怎么将自己做好的网站发布到互联网上呢?

如何将自己的网站上传到网站空间。 1.需要有一个上传网站的软件,在这里推荐大家使用 FTP全称是flashfxp这个软件,这个功能功能齐全而且操作简单。大家可以先去下载一下这个软 件 2. 打开FTP,界面如下 3.我们要点击链接按钮,然后FT…

vue动态生成下拉框_vue+elementui 动态创建下拉框

v-for"(domain, index) in dynamicValidateForm.domains":label"‘站点‘ index":key"domain.id">v-for"item in testData":key"item.id":label"item.testName":value"item.id":disabled"item…

[贝聊科技]网页端「应用跳转」技术实现演变

本文作者:Mr.Luo ,贝聊前端经理。本文同时发布于作者 个人博客 。 由于网页传播的便捷性,从网页向APP导流几乎是所有APP厂商都会采用的推广手段,具体来说就是在网页上提供一些触发点(例如按钮、链接)&#…

常见Java错误的十大列表(前100名!)

前10名名单非常受欢迎,有趣且内容丰富。 但是有很多! 如何选择合适的? 这是一个元前10名列表,可帮助您找到前10名的前10名列表。 在更令人讨厌的笔记上: SELECT TOP 10 mistake FROM source1 UNION ALL SELECT TOP 10…

Ubuntu 16.04 下octave的使用入门

SciLab和octave是开源的且免费的矩阵计算工具,二者都有希望成为矩阵计算的新宠。相比之下, octave与MatLab的兼容性更高。octave遵循GPL协议(GNU General Public License),用户可以单独发行octave或者包含在其产品中发…

hydra mysql 爆破_Hydra(爆破神器)使用方法

文本框 textarea 动态显示行数(简单文本编辑器)工作需求做一个文本编辑器简单的. 右边输入文字,左边会显示相应的代码行.清空也会变为1. 废话不多说上代码,自己理解. python中set使用In [2]: a set() # 常用操作1 In [3]: a Out[3]: set() In [4]: type(a) Out[4]: set In [5]…

消除switch语句以获得更好的代码结构

消除switch语句以获得更好的代码结构 代码演化1:纯switch function counter(state 0, action) {switch (action.type) {case INCREMENT:return state 1case DECREMENT:return state - 1default:return state} }用三元运算符代替 const counter (state 0, ac…

HTTP请求中POST与GET的区别

一、原理区别 一般我们在浏览器输入一个网址访问网站都是GET请求;在FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。 HTTP定义了与服务器交互的不同方法,其中最基本的几种:GET,P…

Linux服务器配置---安装vsftpd

安装vsftpd 大多数Linux系统都使用vsftpd,因此这里我们也安装vsftpd 1、安装vsftpd [rootlocalhost phpMyAdmin]# yum install -y vsftpd Loaded plugins: fastestmirror, refresh-packagekit, security Installed: vsftpd.i686 0:2.2.2-11.el6_4.1 …

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

我认为构造函数和方法中冗长的参数列表是Java开发中的另一个“ 危险信号 ”,就逻辑和功能而言,它们不一定是“错误的”,但通常暗示当前或将来出现错误的可能性很高。 在一小部分帖子中,我介绍了一些可用于减少方法或构造函数的参数…

mysql怎么制作柱状图_从数据库中取出最近三十天的数据并生成柱状图

在终端用cd 命令进入文件目录说明:此处例子我是拿项目中的一个例子讲解的。1、新建一个项目 :用终端输入:zf create project Airline 格式:zf create action project project-name 备注:这些格式可以在终端输入zf 查看…

关于ES6的Promise

JavaScript的异步处理 提到JavaScript的异步处理,也许很多人和我一样想到利用回调函数。 例如: firstAsync(function(data){//处理得到的 data 数据//....secondAsync(function(data2){//处理得到的 data2 数据//....thirdAsync(function(data3){//处…

为hexo博客添加基于gitment评论功能

关于gitment gitment其实就是利用你的代码仓库的Issues,来实现评论。每一篇文章对应该代码仓库中的 一个Issues,Issues中的评论对应你的博客每篇文章中的评论。如果你是用github的博客的话 用起来将会十分的方便。 注册github应用 首先需要在这注册一个OAuth Applic…

[转]我是如何走进黑客世界的?

*本文原创作者:MyselfExplorer;翻译编辑:楼兰,本文属FreeBuf原创奖励计划,未经许可禁止转载 我想给你一把打开这扇门的钥匙,而你要做的便是静静的聆听接下来的故事。挖掘 0day 一般需要掌握fuzzing&#xf…

使用Servlet 3.0,Redis / Jedis和CDI的简单CRUD –第1部分

在这篇文章中,我们将构建一个简单的用户界面。 数据将存储在Redis中。 为了与Redis交互,我们将使用Jedis库。 CDI用于Depedency Injection,而Servlet 3.0用于视图。 让我们从Redis / Jedis部分开始。 您可以在这些 帖子中找到有关Redis和Jed…

Socket.io 深入理解

最近在做项目优化工作时,用到了Socket.io , Socket.io 文档比较少, 结合官网介绍以及自己在项目开发中的摸索,总结如下内容; Socket.io将Websocket和轮询 (Polling)机制以及其它的实时通信方式封装成了通用…

python填表_小Python填表得到d

我正在尝试使用Scrapy从网站自动下载数据。在我要做的是:使用我的凭据登录网站通过在“RIC”行中写入代码并选择感兴趣的时段来选择我想要的数据单击“获取数据”后,将生成.csv文件,我可以从“下载/”url下载该文件,其中我的所有文…

如何使用异步Servlet来提高性能

这篇文章将描述一种性能优化技术,适用于与现代Web应用程序相关的常见问题。 如今的应用程序不再只是被动地等待浏览器发起请求,而是希望自己开始通信。 一个典型的示例可能涉及聊天应用程序,拍卖行等–共同点是以下事实:大多数时间…