Effective Java 第三版——51. 仔细设计方法签名
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方法,该方法接受两个参数并返回子列表的视图。 此方法可以与indexOf或lastIndexOf方法结合使用,这两个方法都有一个参数,以生成所需的功能。 此外,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. 仔细设计方法签名的更多相关文章
- Effective Java 第三版——10. 重写equals方法时遵守通用约定
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- 《Effective Java 第三版》新条目介绍
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
- Effective Java 第三版——49. 检查参数有效性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- effective Java 第三版学习笔记
创建对象类型的 1,静态工厂方法代替构造器 静态工厂方法有名称,不容易混乱他的作用 不必再每次调用他的时候创建实例,创建实例的代价是高的,可以重复利用缓存的对象 静态工厂甚至能返回子类对象,例如在接口 ...
- Effective Java 第三版——21. 为后代设计接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——45. 明智审慎地使用Stream
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- mysql替换字符串
今天要替换数据库里的所有字符串 例如把http改成https UPDATE table_name set colum_name=REPLACE(colum_name,'http','https')
- C#编码、解码
1.HttpUtility.UrlEncode 方法: 对 URL 字符串进行编码,以便实现从 Web 服务器到客户端的可靠的 HTTP 传输.重载列表: [1]将字节数组转换为已编码的 URL 字符 ...
- 手动部署 kubernetes 1.9 记录
前言 目前 kubernetes 正式版本已经到1.10版本.因为前面有大佬(漠然)已经采完坑,所以自己也试着部署 kubernetes 1.9 体验下该版本的新特性.对于前面部署的 kubernet ...
- BZOJ1901 Zju2112 Dynamic Rankings 主席树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...
- 011.Docker仓库管理
一 Docker仓库介绍 docker 仓库,即 registry,实现了镜像的管理.分发,同时还包括用户的认证.docker registry 仓库是一个无状态的.高可靠的服务器应用程序,用来存储d ...
- iOS开发安全
这篇文章之前自己在公司的技术分享学院发表了.现在发到自己的博客上. 现在很多iOS的app没有做任何的安全防范措施.今天我们就聊聊iOS开发人员平时怎么做才更安全. 一.网络方面 用抓包工具可以抓取手 ...
- js基础梳理-究竟什么是变量对象,什么是活动对象?
首先,回顾下上篇博文中js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?的执行上下文的生命周期: 3.执行上下文的生命周期 3.1 创建阶段 生成变量对象(Variable o ...
- 算法进阶面试题03——构造数组的MaxTree、最大子矩阵的大小、2017京东环形烽火台问题、介绍Morris遍历并实现前序/中序/后序
接着第二课的内容和带点第三课的内容. (回顾)准备一个栈,从大到小排列,具体参考上一课.... 构造数组的MaxTree [题目] 定义二叉树如下: public class Node{ public ...
- Leetcode分类总结(Greedy)
贪心类题目目前除了正则匹配(Wildcard Matching)(据说其实是DP)那道还没做其他的免费题目都做了,简单做个总结. 贪心的奥义就是每一步都选择当前回合”可见范围“(即可得知的信息)内的最 ...
- django-用户验证系统
django提供了一套用户验证系统,但是要使用这个系统,必须要使用django内置的用户模型:django.contrib.auth.models.User,这个模型中预先定义了一些字段,其中只有us ...