便利不是一种能力

原文链接

有关优秀API设计的重要与挑战已经说过很多了。一步到位很难,以后改起来更难。有点像把小孩举起来。经验丰富的程序员会认识到,好的API遵循统一的抽象层次,展现出一致性和对称性,并形成富有表达力的语言词汇表。唉,要意识到,知道原则并不会自动转化为合适的行为。吃甜食对你并不好。

我想获取的是一个特定的API设计’策略,’而不是站在高处讲道,我一次又一次遇到:便利的论证。它最典型的就是以以下“洞察”之一开头:

  • 我不希望其他类必须单独调用两次才能完成这件事。
  • 如果新的方法几乎和现在的一样,为什么我还要实现它呢?我仅仅想添加一个简单的选择判断。
  • 看吧,很简单:如果第二个字符串参数是以“.txt”结尾,这个方法就可以自动假设,第一个参数是一个文件名,因此我根本不需要两种方法。

想法是好的,但这种参数容易在代码调用API时降低可读性。一个方法的调用会像这样:

1
parser.processNodes(text, false)

不了解如何实现的情况下实际上是毫无意义的,或者至少要查看下文档。这个方法更像是为了实现者的方便而设计的,而不是调用者的方便——“我不希望调用者必须单独调用两次”可以被理解为“我不想代码被分成两个方法”。如果这是为了对抗乏味、笨拙和尴尬,这些便利本质上来说也没什么错。无论如何,如果我们进一步仔细思考,解决这些症状应该是高效的、统一的且优雅的,而便利性不是必须的。APIs被认为是将复杂性隐藏在其下,所以我们可切实地期望良好的API设计需要一些努力。一个长的方法肯定会比经过一系列深思熟虑的操作更容易编写,但他会更容易使用吗?

API作为一种语言的比喻可以指导我们在这些情况下做出更好的设计决策。API应该提供一种富有表达力的语言,给予下一层充足的词汇表以问答有用的问题。这并不意味着它应该为每个可能有价值的问题都提供确切的方法或动词。一个多样的词汇表能让我们精妙地表达意境。例如:我们倾向于用run来代替walk(true),哪怕是它们本质上是一回事,仅仅是速度上的不同。一个统一且深思熟虑的API词汇可以在下一层上生动表达且易于理解。更重要是,可组合的词汇表允许程序员以你可能没有预料到的方式使用API——确实,API为用户带来了极大的便利!下次你想把一些事情归并到API方法时,请记住,英语是不存在这样一个单词的MakeUpYourRoomBeQuietAndDoYourHomeWork,尽管这种频繁请求方式看起来很便利。

0%