51. 仔细设计方法签名

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

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

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

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

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

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