Convenience Is not an -ility 19

Convenience Is not an -ility
Much has been said about the importance and challenges of designing good API’s. It’s difficult to get right the first time and it’s even more difficult to change later. Sort of like raising children. Most experienced programmers have learned that a good API follows a consistent level of abstraction, exhibits consistency and symmetry, and forms the vocabulary for an expressive language. Alas, being aware of the guiding principles does not automatically translate into appropriate behavior. Eating sweets is bad for you.

Instead of preaching from on high, I want to pick on a particular API design ‘strategy,’ one that I encounter time and again: the argument of convenience. It typically begins with one of the following ‘insights:’

I don’t want other classes to have to make two separate calls to do this one thing.
Why should I make another method if it’s almost the same as this method? I’ll just add a simple switch.
See, it’s very easy: If the second string parameter ends with “.txt”, the method automatically assumes that the first parameter is a file name, so I really don’t need two methods.
While well intended, such arguments are prone to decrease the readability of code using the API. A method invocation like

parser.processNodes(text, false);
is virtually meaningless without knowing the implementation or at least consulting the documentation. This method was likely designed for the convenience of the implementer as opposed to the convenience of the caller — “I don’t want the caller to have to make two separate calls” translated into “I didn’t want to code up two separate methods.” There’s nothing fundamentally wrong with convenience if it’s intended to be the antidote to tediousness, clunkiness, or awkwardness. However, if we think a bit more carefully about it, the antidote to those symptoms is efficiency, consistency, and elegance, not necessarily convenience. APIs are supposed to hide underlying complexity, so we can realistically expect good API design to require some effort. A single large method could certainly be more convenient to write than a well thought-out set of operations, but would it be easier to use?

The metaphor of API as a language can guide us towards better design decisions in these situations. An API should provide an expressive language, which gives the next layer above sufficient vocabulary to ask and answer useful questions. This does not imply it should provide exactly one method, or verb, for each question that may be worth asking. A diverse vocabulary allows us to express subtleties in meaning. For example, we prefer to say run instead of walk(true), even though it could be viewed as essentially the same operation, just executed at different speeds. A consistent and well thought out API vocabulary makes for expressive and easy to understand code in the next layer up. More importantly, a composable vocabulary allows other programmers to use the API in ways you may not have anticipated — a great convenience indeed for the users of the API! Next time you are tempted to lump a few things together into one API method, remember that the English language does not have one word for MakeUpYourRoomBeQuietAndDoYourHomeWork, even though it would seem really convenient for such a frequently requested operation.

By Gregor Hohpe

关于设计好的API的重要性和挑战,已经说过很多了。第一次很难做到正确,以后更难改变。有点像抚养孩子。大多数有经验的程序员都知道,一个好的API遵循一致的抽象级别,表现出一致性和对称性,并形成表达性语言的词汇表。遗憾的是,意识到指导原则并不能自动转化为适当的行为。吃甜食对你不好。
我不想高谈阔论,而是想选择一种特定的API设计“策略”,一种我反复遇到的策略:便利性的论点。它通常以以下“见解”之一开头:
我不希望其他类必须进行两个单独的调用才能完成这一件事。
如果它和这个方法几乎一样,为什么我要做另一个方法?我只添加一个简单的开关。
看,这很容易:如果第二个字符串参数以“.txt”结尾,该方法会自动假设第一个参数是文件名,所以我真的不需要两个方法。
虽然这是出于好意,但此类参数很容易降低使用API的代码的可读性。像这样的方法调用
parser.processNodes(文本,false);
在不了解实现或至少查阅文档的情况下,实际上是毫无意义的。这个方法可能是为了实现者的方便而设计的,而不是为了调用方的方便-“我不希望调用方必须进行两个单独的调用”翻译成“我不想编写两个单独方法的代码”。如果它是为了缓解乏味、笨拙或尴尬,那么方便就没有什么根本问题。然而,如果我们仔细想想,这些症状的解药是效率、一致性和优雅,而不一定是方便。API应该隐藏潜在的复杂性,所以我们可以实际地期望好的API设计需要付出一些努力。一个单独的大方法肯定比一组经过深思熟虑的操作更方便编写,但它会更容易使用吗?
API作为一种语言的隐喻可以指导我们在这些情况下做出更好的设计决策。API应该提供一种富于表现力的语言,它为下一层提供了足够的词汇来提问和回答有用的问题。这并不意味着它应该为每个可能值得问的问题提供一个方法或动词。多样化的词汇使我们能够表达微妙的意思。例如,我们更喜欢说跑步而不是步行(true),尽管它可以被视为本质上相同的操作,只是以不同的速度执行。一致且深思熟虑的API词汇表有助于下一层代码的表达和理解。更重要的是,可组合词汇表允许其他程序员以您可能没有预料到的方式使用API,这对API用户来说确实是一个极大的方便!下一次,当您试图将一些东西合并到一个API方法中时,请记住,英语中没有一个单词表示MakeUpYourRoomBeQuietAndDoYourHomeWork,即使对于这样一个频繁请求的操作来说,它看起来确实很方便。
作者Gregor Hohpe

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值