方便不是-ility
善于设计良好的API的重要性和挑战性已经说过很多了。第一次就做对是很难的,以后要修改则更不容易。有点像养育孩子。大多数有经验的程序员都知道良好的API遵从一致水平的抽象,展示出一致性和对称性,形成了一种有表现力的语言词汇。哎,了解这些指导原则并不能自动转换成恰当的行为。吃甜食是不好的。
不用大道理进行布道,我想选择一个特别的API设计“策略"开始说,这是我经常遇到的一个:便利性的观点。它经常以如下“见解”开始:
· 我不想其它的类在做这一件事时要调用两个接口。
· 如果几乎和这个方法一样,我为什么还要另外再做一个呢?只需要增加一个简单的switch就可以了。
· 看,这很简单:如果第二个参数以“.txt”结尾,这个方法会自己假设第一个参数是一个文件名,所以我不需要两个方法。
尽管出发点是好的,这点观点有降低使用这些API的代码的可读性的倾向。一个象这样的方法调用:
parser.processNodes(text, false);
实际上在不知道实现方法或者参阅文档的情况下是没有意义的。这个方法像是设计来方便实现者而不是方便使用者——“我不想其它的类在做这一件事时要调用两个接口”变成了“我不想编码实现两个接口”。如果便利性本意是消除沉闷、笨重和拙劣的药剂,那它在本质上是没错的。但是,如果我们再仔细想想,消除这些病症的药剂其实是效率、一致性和雅致,便利性不是必需的。API应该是隐藏下层的复杂性,所以我们应该很现实地预计到设计记好的API是需要努力的。一个单一的大方法当然比一组深思熟虑的操作集合写起来要方便,但它会很容易使用吗?
将API比喻成语言,可以在这些情况下指导我们作出更好的设计决定。API应该提供一个富有表现力的语言,给上一层提提供充足的词汇询问和回答有用的问题。这并不是说它应该刚好提供一个方法、动词或者可能值得问的问题。各种各校的词汇可以让我们表达意思上微妙的东西。例如,我们喜欢说run来代替walk(true),即便可以认为它们本质上是相同的操作,只不过是以不同的速度执行。一致的、经过深思熟虑的API在词汇上更富表现力,可以让上一层更加容易理解。更重要的是,组合的词汇可以让使用该API的其他程序员用你尚未预计的方式调用——这才是真的会大大方便用户的API!下次你尝试把一个东西搅到一起并入一个API时,记住英文中并没有MakeUpYourRoomBeQuietAndDoYourHomeWork这么个词,即使看起来这对一个频繁请求的操作是很方便。