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

在当前的系列文章中,我正在致力于减少调用Java方法和构造函数所需的参数数量,到目前为止,我一直专注于直接影响参数本身的方法( 自定义类型 , 参数对象 , 构建器模式 , 方法重载和方法命名 )。 鉴于此,对于本系列中的一篇文章,我专门讨论Java方法如何提供返回值,这似乎让我感到惊讶。 但是,方法的返回值会影响开发人员选择通过设置或更改提供的参数(而不是附加或添加更传统的方法返回机制)来提供“返回”值时方法所接受的参数。

非构造方法返回值的“传统方式”都可以在方法签名中指定。 从Java方法返回值的最普遍认可的方法是通过其声明的return type 。 这通常效果很好,但是最常见的一种挫败是允许其仅从 Java方法返回一个值 。

Java的异常处理机制也是将方法的“结果”保留给调用者的另一种方法。 特别是, 经过检查的异常通过throws子句通告给调用者。 实际上, Jim Waldo在他的《 Java:The Good Parts》一书中指出,当人们将Java异常视为另一种方法返回限制为Throwable类型时,更容易理解Java异常。

尽管方法的返回类型和抛出的异常旨在作为方法将信息返回给调用方的主要方法,但有时还是很想通过传递给方法的参数来返回数据或状态。 当一个方法需要返回多个信息时,Java方法的单值返回似乎是有限的。 尽管异常提供了另一种与调用方进行通信的方式,但似乎几乎所有人都同意,异常应仅用于报告异常情况,而不能用于报告“正常”数据或在控制流中使用。 鉴于只能从一种方法返回一个对象或原语,并且异常仅允许返回Throwable且应仅将其用于报告异常情况,因此Java开发人员劫持参数作为返回数据的替代途径变得越来越有吸引力给来电者。

开发人员可以用来将方法参数用作返回数据的载体的技术是接受可变的参数并改变传入对象的状态。 这些可变对象可以通过方法更改其内容,然后调用者可以访问它提供的对象,以确定被调用方法应用的新状态设置。 尽管可以使用任何可变对象来完成此操作,但对于试图通过参数将值传递回调用方的开发人员而言,集合似乎特别有吸引力。

通过提供的参数将状态传递回被调用有一些缺点。 由于大多数Java开发人员可能期望参数传入而不是传出(并且Java不提供任何代码支持来指定差异),所以这种方法通常违反了令人惊讶的原则 。 鲍勃·马丁(Bob Martin)在他的《 清洁代码 》一书中这样写道 :“通常应避免输出参数。” 使用参数作为方法向调用者提供状态或输出的方法的另一个缺点是,这会增加传递给方法的参数的混乱程度。 考虑到这一点,本文的其余部分重点介绍通过传入的参数返回多个值的替代方法。

尽管Java方法只能返回一个对象或基元,但是当人们认为一个对象可以是我们想要的任何对象时,这实际上并不是什么限制。 我见过几种方法,但不推荐使用。 其中之一是返回对象实例的数组或集合,每个Object都是完全不同的,通常是不相关的“事物”。 例如,该方法可能返回三个值作为数组或集合的三个元素。 这种方法的一种变体是使用一对元组或n大小的元组返回多个关联值。 此方法的另一个变体是返回Java Map,该Java Map将任意键映射到它们的关联值。 与其他解决方案一样,此方法会给客户端带来不必要的负担,让他们知道那些键是什么,并通过这些键访问映射值。

下一个代码清单包含几种不那么吸引人的方法来返回多个值,而不会劫持方法参数以返回多个值。

通过通用数据结构返回多个值

// ===============================================================// NOTE: These examples are intended solely to illustrate a point//       and are NOT recommended for production code.// ===============================================================/*** Provide movie information.* * @return Movie information in form of an array where details are mapped to* elements with the following indexes in the array:*       0 : Movie Title*       1 : Year Released*       2 : Director*       3 : Rating*/public Object[] getMovieInformation(){final Object[] movieDetails ={"World War Z", 2013, "Marc Forster", "PG-13"};return movieDetails;}/*** Provide movie information.* * @return Movie information in form of a List where details are provided* in this order: Movie Title, Year Released, Director, Rating.*/public List<Object> getMovieDetails(){return Arrays.<Object>asList("Ender's Game", 2013, "Gavin Hood", "PG-13");}/*** Provide movie information.* * @return Movie information in Map form. Characteristics of the movie can* be acquired by looking in the map for these key elements: "Title", "Year",* "Director", and "Rating"./*/public Map<String, Object> getMovieDetailsMap(){final HashMap<String, Object> map = new HashMap();map.put("Title", "Despicable Me 2");map.put("Year", 2013);map.put("Director", "Pierre Coffin and Chris Renaud");map.put("Rating", "PG");return map;}

上面显示的方法确实满足了不通过调用的方法的参数将数据传递回调用方的意图,但是调用方仍然没有必要负担来知道返回数据结构的详细信息。 减少方法的参数数量并且不违反最小惊喜原则是很好的,但是要求客户知道复杂数据结构的复杂性并不是很好。

当我需要返回多个值时,我更喜欢为返回值编写自定义对象。 与使用数组,集合或元组结构相比,这需要做更多的工作,但是很少的额外工作(对于现代Java IDE,通常需要几分钟的时间)会带来可读性和流利性,而这是这些更通用的方法所不具备的。 我的自定义返回对象不必在Javadoc上进行解释或要求我的代码的用户仔细阅读我的代码即可知道在数组或集合中按哪个顺序提供了哪些参数,或者在元组中按哪个值提供了这些参数,而不必在对象上定义方法他们告诉客户他们到底提供了什么。

接下来的代码片段说明了一个主要由NetBeans生成的简单Movie类,该类可以用作返回类型,并且可以返回该类的实例的代码,而不是更通用,更易读的数据结构。

电影.java

package dustin.examples;import java.util.Objects;/*** Simple Movie class to demonstrate how easy it is to provide multiple values* in a single Java method return and provide readability to the client.* * @author Dustin*/
public class Movie
{private final String movieTitle;private final int yearReleased;private final String movieDirectorName;private final String movieRating;public Movie(String movieTitle, int yearReleased, String movieDirectorName, String movieRating){this.movieTitle = movieTitle;this.yearReleased = yearReleased;this.movieDirectorName = movieDirectorName;this.movieRating = movieRating;}public String getMovieTitle(){return movieTitle;}public int getYearReleased(){return yearReleased;}public String getMovieDirectorName(){return movieDirectorName;}public String getMovieRating(){return movieRating;}@Overridepublic int hashCode(){int hash = 3;hash = 89 * hash + Objects.hashCode(this.movieTitle);hash = 89 * hash + this.yearReleased;hash = 89 * hash + Objects.hashCode(this.movieDirectorName);hash = 89 * hash + Objects.hashCode(this.movieRating);return hash;}@Overridepublic boolean equals(Object obj){if (obj == null){return false;}if (getClass() != obj.getClass()){return false;}final Movie other = (Movie) obj;if (!Objects.equals(this.movieTitle, other.movieTitle)){return false;}if (this.yearReleased != other.yearReleased){return false;}if (!Objects.equals(this.movieDirectorName, other.movieDirectorName)){return false;}if (!Objects.equals(this.movieRating, other.movieRating)){return false;}return true;}@Overridepublic String toString(){return "Movie{" + "movieTitle=" + movieTitle + ", yearReleased=" + yearReleased + ", movieDirectorName=" + movieDirectorName + ", movieRating=" + movieRating + '}';}
}

在单个对象中返回多个详细信息

/*** Provide movie information.* * @return Movie information.*/public Movie getMovieInfo(){return new Movie("Oblivion", 2013, "Joseph Kosinski", "PG-13");}

Movie课的简单写作花了我大约5分钟的时间。 我使用NetBeans类创建向导来选择类名称和包,然后键入该类的四个属性。 从那里开始,我仅使用NetBeans的“插入代码”机制来插入“获取”访问器方法以及重写的toString() , hashCode()和equals(Object)方法。 如果我认为不需要这些,可以简化类,但按原样创建确实很容易。 现在,我有一个更有用的返回类型,这由使用该类的代码反映出来。 它几乎不需要在返回类型上使用Javadoc注释,因为该类型可以说明一切,并使用“ get”方法发布其内容。 我觉得,与通过方法参数返回状态或使用更通用且更难使用的返回数据结构之类的替代方法相比,创建这些简单的类以返回多个值的少量额外工作将获得丰厚的回报。

保留要返回给调用方的多个值的自定义类型是一种有吸引力的解决方案,这并不奇怪。 毕竟,从概念上讲,这与我之前写过的关于博客的概念非常相似,后者涉及使用自定义类型和参数对象来传递多个相关参数,而不是将它们全部单独传递。 Java是一种面向对象的语言,当我没有看到在Java代码中使用对象来组织好参数并在一个不错的包中返回值时,它使我感到惊讶。

优势与优势

使用自定义参数对象表示和封装多个返回值的优点是显而易见的。 方法的参数可以保留为“输入”参数,因为所有输出信息(通过异常机制传达的错误信息除外)都可以在方法返回的自定义对象中提供。 与使用通用数组,集合,地图,元组或其他通用数据结构相比,这是一种更清洁的方法,因为所有这些替代方法都将开发工作转移到了所有潜在客户上。

成本与劣势

我看到编写具有多个值的自定义类型用作Java方法的返回类型的缺点很小。 也许最常声称的成本是编写和测试这些类的价格,但是该成本非常小,因为这些类往往很简单,并且因为现代IDE为我们完成了大部分工作。 因为IDE是自动执行的,所以代码通常是正确的。 这些类非常简单,以使代码审阅者易于阅读,并且易于测试。

为了寻找其他成本和劣势,人们可能会争辩说这些类会膨胀代码库和程序包,但我认为这不是一个强有力的论据。 尽管自定义类实现不好的风险很小,但我认为客户机代码更容易混淆更通用的返回类型的解释。 另一个小风险是,开发人员可能将很多无关的东西扔到同一个类中,而这些项目之间的唯一关系是,相同的方法需要返回它们。 即使这样,我能看到的唯一更好的选择是修改代码,而无需返回多个值。 在自定义对象中返回原本不相关的项似乎仍然比在通用数据结构中返回这组不相关的数据更好。 实际上,这些通用数据结构变得更加笨拙并且难以使用,因为它们所拥有的值变得越来越不相关。

结论

自定义类型和参数对象可帮助我们直接解决Java方法中过多参数的问题。 幸运的是,这些自定义类型和返回值对象还可以通过允许我们通过自定义类型和返回值对象返回多个值,而无需添加仅用于将输出信息传递回去的附加参数,从而帮助我们间接减少所需参数的数量。呼叫者,召集者。

参考: Java方法中的参数太多,第6部分: JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客上的方法返回 。

翻译自: https://www.javacodegeeks.com/2013/11/too-many-parameters-in-java-methods-part-6-method-returns.html

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

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

相关文章

2017前端技术大盘点

前言 临近2017的尾声&#xff0c;总是希望来盘点一下这一年中前端的发展。到目前为止&#xff0c;前端的井喷期也快临近尾声了。并不像几年前一样&#xff0c;总是会有层出不穷的新东西迸发出来。同时&#xff0c;前端技术也慢慢的趋于稳固&#xff0c;自成一套体系。如果你喜…

jenkins pipeline api获取stage的详细信息_Jenkins + Docker 助力 Serverless 应用构建与部署...

本文来源&#xff1a; ServerlessLife 公众号近日&#xff0c;使用 Serverless 开发了一个应用。其中 CI/CD&#xff0c;是需要考虑的一个问题。这里用到了 Jenkins 和 Docker。并且 Jenkins Pipeline 运行在容器中。本文将介绍如何使用 Jenkins 和 Docker 构建并部署 Serverle…

BZOJ 1305 [CQOI2009]dance跳舞

这是一道最大流的模版题 一定要记住不能开出来重点呀 #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN205; const int MAXM6005; const int inf0x3f3f3f…

项目本地部署

1.将数据库导出&#xff0c;并导入到本地 exp dgpdg/pass192.168.1.33/ORCL fileD:\gd_base.dmp logD:\gd_base.log&#xff08;不要加fully&#xff0c;会把整个数据库下所有用户的表倒下来&#xff09; imp dgpdg/pass127.0.0.1/orcl file"D:\gd_base.dmp" log&quo…

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

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

命名空间不能直接包含字段或方法之类的成员是什么意思_Python 学习笔记之类与实例...

Python 学习笔记之类与实例一、定义1.1、定义类 (class) 封装一组相关数据&#xff0c;使之成为一个整体&#xff0c;并使用一种方法持续展示和维护。这有点像把零件组装成整车提供给用户&#xff0c;无须了解汽车的内部结构和工作原理&#xff0c;只要知道方向盘&#xff0c;刹…

跨平台开发框架 Lynx 初探

跨平台开发是目前开发较热门的方向&#xff0c;React Native 在这方面取得了很大的成功&#xff0c;同时 Flutter 也获得了非常多的关注。React Native 采用 Web 框架开发并使用 Native UI 进行渲染&#xff0c;很大程度上降低了 Native 开发的门槛并且提高迭代的效率&#xff…

linux ubuntu 关于vim得一些基本命令

&#xff11;.vim显示行号 :set number 2. 快捷键 J 向下 K 往上 H 向左 L 向右 ctrlshiftT  打开新窗口 ctrlPage Down 所有vim窗口向下切换 ctrlPage Up 所有vim窗口向上切换 &#xff13;. 复制vim打开的内容 yy 复制光标所在行 2yy 复制光标所在行往下的两行 ....…

ajax包含mysql吗_php 实例ajax与mysql怎么只查询出一条数据?

http://www.runoob.com/php/php...使用这个实例操作之后为什么只显示一条数据&#xff0c;如何让符合条件的数据全部显示出来如&#xff0c;我使用的查询字段是yesterday_str&#xff0c;查询2017-04-18这个数据怎么样才能把2017-04-18包含这个的全部数据提取出来&#xff1f;p…

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

在本文中&#xff0c;我们将重点介绍CDI和Servlet 3.0。 您可以在此处看到第1部分。 让我们从CDI开始。 当我开始撰写源自该系列的文章时&#xff0c;我并没有考虑撰写CDI。 真诚地说&#xff0c;我以前从未使用过。 这篇文章的想法是使用jedis和servlet创建一个对象。 但是&a…

Safari支持Service Worker,PWA还有多久爆发?

作者 | 彭星 编辑 | 尾尾 在之前的文章《PWA 将带来新一轮大前端技术洗牌&#xff1f;》中&#xff0c;我们回顾了 Web 在移动时代遭遇的两大枷锁&#xff0c;并就PWA是否能真正弥补 Web 劣势进行了分析&#xff0c;同时&#xff0c;提出“根据当前的发展趋势&#xff0c;PWA…

安装python3 及virtual与virtualenvwrapper

安装python3 下载python源码包 网址&#xff1a;https://www.python.org/downloads/release/python-362/ 下载地址&#xff1a;https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tar.xz 安装python前的库环境&#xff0c;非常重要 yum install gcc patch libffi-devel py…

响应式设计与前端工程性

一&#xff1a;响应式的几个基本知识 字体选择 有衬线和无衬线&#xff0c;那种字体看自己的美学意识和考虑 透视比例与体验一致性保证&#xff08;人眼的位置&#xff09; 行高&#xff0c;字体大小&#xff0c;间距&#xff0c;要根据整个展示范围的透视比例合理的去规划pc 离…

aspx写入mysql_Asp.net用户登陆数据库验证与注册写入数据库

1.思路与效果图Index.aspx注册注册成功登陆登陆验证通过进入内容页1登陆没通过验证思路&#xff1a;首先建一个Sqlserver数据库Student,再建一个student表(name,pwd)存放用户名和密码。然后注册功能的实现&#xff1a;通过数据库插入信息到表的Sql语句来实现&#xff0c;成功提…

在WildFly中将Apache Camel和Spring添加为jboss模块

这些天&#xff0c;我在玩Wildfly &#xff0c; Apache Camel和Spring 。 在EAR / WAR之间进行通信的一种简单方法是使用Camel的direct-vm组件。 有或没有骆驼&#xff0c;有很多方法可以实现这一目标。 骆驼在WildFly中就像一个饰物&#xff0c;不需要任何额外的配置。 骆驼很…

页面体验提升小技巧—渐进式图片

前端性能方面有许多可优化的点&#xff0c;而这些优化带来的就是用户体验的提升。今天我们要聊的东西并不能给性能带来提升&#xff0c;但却能在一定程度上提升用户的体验。 参考博客 场景&#xff1a;在访问页面的时候如果图片较大或者网速慢的情况我们会看到图片加载起来是有…

php mysql无限分类排序_PHP 无限级分类、排序

lyk625358header(content-type:text/html;charsetutf-8);echo "";//-无限级排序,自己优化改良的,清除上次调用此函数后留下的静态变量的值$arr array(array(id>2,cname>分类2,parent_id>1),array(id>9,cname>分类9,parent_id>8),array(id>1,cn…

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

在上一篇文章 &#xff08;有关处理Java方法中过多参数的系列文章的 第4部分 &#xff09;中&#xff0c;我将方法重载视为一种向客户提供需要较少参数的方法版本或构造函数的方法。 我描述了该方法的一些缺点&#xff0c;并建议从方法重载中摆脱出来以使用不同名称的方法至少可…

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

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

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

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