Tips

书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code

注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

51. 仔细设计方法签名

这一条目是API设计提示的大杂烩,但它们本身并足以设立一个单独的条目。综合起来,这些设计提示将帮助你更容易地学习和使用API,并且更不容易出错。

仔细选择方法名名称。名称应始终遵守标准命名约定(条目68)。你的主要目标应该是选择与同一包中的其他名称一致且易于理解的名称。其次是应该是选择与更广泛的共识一致的名称。避免使用较长的方法名。如果有疑问,可以从Java类库API中寻求指导。尽管类库中也存在许多不一致之处(考虑到这些类库的规模和范围,这是不可避免的),也提供了相当客观的认可和共识。

不要过分地提供方便的方法。每种方法都应该“尽其所能”。太多的方法使得类难以学习、使用、文档化、测试和维护。对于接口更是如此,在接口中,太多的方法使实现者和用户的工作变得复杂。对于类或接口支持的每个操作,提供一个功能完整的方法。只有在经常使用时,才考虑提供“快捷方式(shortcut)”。如果有疑问,请将其删除

避免过长的参数列表。目标是四个或更少的参数。大多数程序员不能记住更长的参数列表。如果你的许多方法超过了这个限制,如果未经常引用其文档的情况下,那么你的API将无法使用。现代IDE编辑器会提供帮助,但是使用简短的参数列表仍然会更好。相同类型参数的长序列尤其有害。用户不仅不能记住参数的顺序,而且当他们意外地弄错参数顺序时,他们的程序仍然会编译和运行。只是不会按照作者的意图去执行。

有三种技术可以缩短过长的参数列表。 一种方法是将方法分解为多个方法,每个方法只需要参数的一个子集。 如果不小心,这可能会导致太多方法,但它也可以通过增加正交性(orthogonality)来减少方法个数。 例如,考虑java.util.List接口。 它没有提供查找子列表中元素的第一个或最后一个索引的方法,这两个索引都需要三个参数。 相反,它提供了subList方法,该方法接受两个参数并返回子列表的视图。 此方法可以与indexOflastIndexOf方法结合使用,这两个方法都有一个参数,以生成所需的功能。 此外,subList方法可以与在List实例上操作的任何方法组合,以对子列表执行任意计算。 得到的API具有非常高的功率重量( power-to-weight)比。

缩短过长参数列表的第二种技术是创建辅助类来保存参数组。这些辅助类通常是静态成员类(条目24)。如果看到一个频繁出现的参数序列表示某个不同的实体,建议使用这种技术。例如,假设正在编写一个表示纸牌游戏的类,并且发现不断地传递一个由两个参数组成的序列,这些参数表示纸牌的点数和花色。如果添加一个辅助类来表示卡片,并用辅助类的单个参数替换参数序列的每次出现,那么API和类的内部结构可能会受益。

结合前两个方面的第三种技术是,从对象构造到方法调用采用Builder模式(条目2)。如果你有一个方法有许多参数,特别是其中一些是可选的,那么可以定义一个对象来表示所有的参数,并允许客户端在这个对象上进行多个“setter”调用,每次设置一个参数或较小相关的组。设置好所需的参数后,客户端调用对象的“execute”方法,该方法对参数进行最后的有效性检查,并执行实际的计算。

对于参数类型,优先选择接口而不是类(条目64)。如果有一个合适的接口来定义一个参数,那么使用它来支持一个实现该接口的类。例如,没有理由在编写方法时使用HashMap作为输入参数,相反,而是使用Map作为参数,这允许传入HashMap、TreeMap、ConcurrentHashMap、TreeMap的子Map(submap)或任何尚未编写的Map实现。通过使用的类而不是接口,就把客户端限制在特定的实现中,如果输入数据碰巧以其他形式存在,则强制执行不必要的、代价高昂的复制操作。

与布尔型参数相比,优先使用两个元素枚举类型,除非布尔型参数的含义在方法名中是明确的。枚举类型使代码更容易阅读和编写。此外,它们还可以方便地在以后添加更多选项。例如,你可能有一个Thermometer类型的静态工厂方法,这个方法的签名是以下这个枚举:

public enum TemperatureScale { FAHRENHEIT, CELSIUS }

Thermometer.newInstance(TemperatureScale.CELSIUS)不仅比Thermometer.newInstance(true)更有意义,而且可以在将来的版本中将KELVIN添加到TemperatureScale中,而无需向Thermometer添加新的静态工厂。 此外,还可以将温度刻度(temperature-scale)依赖关系重构为枚举常量的方法(条目34)。 例如,每个刻度常量可以有一个采用double值并将其转换为Celsius的方法。

Effective Java 第三版——51. 仔细设计方法签名的更多相关文章

  1. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  4. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  5. Effective Java 第三版——49. 检查参数有效性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. effective Java 第三版学习笔记

    创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ...

  7. Effective Java 第三版——21. 为后代设计接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——45. 明智审慎地使用Stream

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. asp.net core 微信公众号支付(扫码支付,H5支付,公众号支付,app支付)之3

    在微信公众号中访问手机网站,当需要调用支付时候无法使用H5支付,只有使用微信公众号支付,使用公众号支付用户必须关注该公众号同时该公众号必须开通公众号支付功能. 1.获取用户的OpenId ,参考之前写 ...

  2. K-means聚类算法及python代码实现

    K-means聚类算法(事先数据并没有类别之分!所有的数据都是一样的) 1.概述 K-means算法是集简单和经典于一身的基于距离的聚类算法 采用距离作为相似性的评价指标,即认为两个对象的距离越近,其 ...

  3. BZOJ1201 [HNOI2005]数三角形 大力出奇迹

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1201 题意概括 题解 n3跑过去了,大力出奇迹!简单的,不多说了. 代码 #include < ...

  4. cookie和session、

    https://my.oschina.net/yoyo1987/blog/156117 Session会在浏览器关闭后消失吗? 通常情况下,当我们关闭浏览器再重新打开后,我们就需要再次进行登陆(如果没 ...

  5. Python 扩展技术总结(转)

    一般来说,所有能被整合或导入到其他Python脚本中的代码,都可以称为扩展.你可以用纯Python来写扩展,也可以用C/C++之类的编译型语言来写扩展,甚至可以用java,C都可以来写 python扩 ...

  6. Python常用模块--base64

    作用:对一些保密性不强的信息进行加密,变为人类不能直接理解的字符串,但是可以反向解密,是一种‘防君子,不防小人’的措施. 例如:在一些项目中,接口的报文是通过base64加密传输的,所以在进行接口自动 ...

  7. 不一样的go语言之入门篇-Hello World

      这是<不一样的go语言>的开篇之作,我尝试以java语言转变者的角度来聊一聊go语言.所以今天先从go语言的基础开始,即语法.   学习一门新的编程语言,必从语法开始.但需要注意的是, ...

  8. SpringMVC中ModelAndView对象与“视图解析器”

    摘要: spring MVC这个环境中,Spring MVC会依据controller(或者你叫它handler)中处理方法的返回值,进行解析,解析之后提供一个视图,作为响应. 标注了@Control ...

  9. 连接池commons-pool2

    commons-pool2池技术可以应用在对象上构建对象池,也可以用在http连接或者netty连接 构建连接池,池技术为了节省对象创建销毁或连接资源频繁申请销毁带来的时间消费. 当用于连接池在进行扩 ...

  10. BZOJ.1758.[WC2010]重建计划(分数规划 点分治 单调队列/长链剖分 线段树)

    题目链接 BZOJ 洛谷 点分治 单调队列: 二分答案,然后判断是否存在一条长度在\([L,R]\)的路径满足权值和非负.可以点分治. 对于(距当前根节点)深度为\(d\)的一条路径,可以用其它子树深 ...