这个项目是一个API设计提示的大杂烩,它们并不完全值得拥有自己的项目。总之,它们将帮助您的API更容易学习和使用,并且更不容易出错。
仔细选择方法名称。名称应始终遵循标准命名约定(item68 )。您的主要目标应该是选择可理解的、与同一包中的其他名称一致的名称。你的第二个目标应该是选择与更广泛的共识相一致的名字。避免长方法名。如果有疑问,可以参考Java库api。尽管存在大量的矛盾——考虑到这些图书馆的规模和范围,这是不可避免的——但也存在相当多的共识。
不要过分提供方便的方法。每种方法都应该“各司其职”。太多的方法使得类难以学习、使用、记录、测试和维护。对于接口来说更是如此,在接口中,太多的方法使实现者和用户的生活变得复杂。对于类或接口支持的每个操作,请提供一个全功能方法。只有在经常使用时才考虑提供“速记”。当你有疑问的时候,把它排除在外。
避免长参数列表。目标是四个或更少的参数。大多数程序员记不住更长的参数列表。如果您的许多方法超过了这个限制,那么如果没有对其文档的不断引用,您的API将无法使用。现代ide有所帮助,但是使用简短的参数列表仍然会让您的情况好得多。长序列的同类型参数尤其有害。用户不仅不能记住参数的顺序,而且当他们不小心转置参数时,他们的程序仍然会编译和运行。它们只是不会按照作者的意图去做。
有三种技术可以缩短过长的参数列表。一种方法是将方法分解为多个方法,每个方法只需要参数的一个子集。如果不小心操作,这可能导致太多的方法,但它也可以通过增加正交性来帮助减少方法数量。例如,考虑java.util.List 接口。它不提供查找子列表中元素的第一个或最后一个索引的方法,这两个方法都需要三个参数。相反,它提供了子列表方法,该方法接受两个参数并返回子列表的视图。他的方法可以与indexOf或lastIndexOf方法相结合,其中每个方法都有一个参数,从而生成所需的功能。此外,子列表方法可以与操作列表实例的任何方法组合使用,以执行子列表上的任意计算。得到的API具有非常高的功率-重量比。
缩短长参数列表的第二种技术是创建helper类来保存参数组。通常这些helper类是静态成员类( item24 )。如果经常出现的参数序列表示一些不同的实体,则推荐使用这种技术。例如,假设您正在编写一个表示纸牌游戏的类,您发现自己不断地传递一个序列,其中包含两个参数,分别表示纸牌的等级和花色。如果您添加一个helper类来表示一张卡片,并用helper类的一个参数替换参数序列中的每个出现的参数,那么您的API以及类的内部结构都可能受益。
结合前两个方面的第三种技术是将Builder模式( item2)从对象构造调整到方法调用。如果你有一个方法与许多参数,特别是其中一些是可选的,它可以有利于定义一个对象,代表所有的参数,并允许客户端进行多个“setter”调用这个对象,每一个都设置一个参数或小,相关的组。一旦设置了所需的参数,客户机就调用对象的“execute”方法,该方法对参数进行任何最终有效性检查并执行实际计算。
对于参数类型,首选接口而不是类( item64 )。如果有合适的接口来定义参数,那么使用它来支持实现该接口的类。例如,没有理由编写一个在输入中使用HashMap而不是HashMap的方法。这允许您传入HashMap、TreeMap、ConcurrentHashMap、TreeMap的子映射或任何尚未编写的映射实现。通过使用类而不是接口,您可以将客户端限制在特定的实现中,如果输入数据碰巧以某种其他形式存在,则强制执行不必要的、可能代价很高的复制操作。
比起布尔参数,更喜欢双元素枚举类型,除非从方法名中明确布尔值的含义。枚举使代码更容易读和写。此外,它们使以后添加更多选项变得更加容易。例如,你可能有一个温度计类型与静态工厂,采取这个枚举:
public enum TemperatureScale { FAHRENHEIT, CELSIUS }
仅温度计. newinstance (temperature . newinstance .摄氏度)比温度计. newinstance (true)更有意义,而且您可以在将来的版本中向温标添加开尔文,而不必向温度计添加新的静态工厂。此外,您还可以将温度尺度依赖关系重构为enum常量上的方法(item34)。例如,每个比例常数都有一个方法,该方法取一个双值并将其转换为摄氏度。
本文写于2019.7.17,历时1天
网友评论