Convenience Is Not an -ility

Convenience Is Not an -ility

Gregor Hohpe

MUCH HAS BEEN SAiD about the importance and challenges of designing good APIs. 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, exhib- its 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 filename, 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 consult- ing 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

??38 97 Things Every Programmer Should Know

?

???????????????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 real- istically 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 toward 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 that 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 impor- tantly, 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 be really convenient for such a frequently requested operation.

时间: 2024-10-10 01:00:40

Convenience Is Not an -ility的相关文章

ARTS Week 10

Dec 30, 2019 ~ Jan 5, 2020 Algorithm Problem 88 Merge Sorted Array (合并两个有序数组) 题目链接 题目描述:给定两个有序数组 nums1,nums2,其长度分别为m,n.假设 nums1 有足够的空间(m+n),将 nums2 中的数组添加到已有的 nums1 数组中.不返回任何值.举例如下: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 合并后的 nums1 =?[1,

Swift的 convenience && designated init

http://www.th7.cn/Program/IOS/201603/789227.shtml 在 OC 中 init 方法是非常不安全的,没人能够保证 init 只被调用一次,也没有人保证在初始化方法调用以后实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的的话,还可能会造成各种问题.Swift 强化了 designated 初始化方法的地位.swift 中不加修饰的 init 方法都需要在方法中保证所有非 Optional 得实例变量被赋值初始化,而在子类中也强制(显示或隐

Swift-04-Designated&&Convenience

class ClassA { let numA:Int init(num: Int){ numA = num } } class ClassB: ClassA { let numB:Int override init(num: Int) { numB = num + 1 super.init(num: num) } } 我们可以在init里面对let的实例变量进行赋值,这是初始化方法的重要特点.在Swift中,let声明的值是不变量,无法被写入赋值,这对构建线程安全的API十分有用.而因为ini

swift语言点评十七-Designated Initializers and Convenience Initializers

Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. These are known as designated initializers and convenience initializers. Designated:指定的:特指的 全初始化与部分初始化 Designated Initializers and

英语词根词缀记忆大全

第一部分 通过词缀认识单词 (常用前缀一) 1.a- ① 加在单词或词根前面,表示"不,无,非" acentric 无中心的(a+centric中心的) asocial 不好社交的(a+social好社交的) amoral 非道德性的(a+moral道德的:注意:immoral不道德的) apolitical. 不关政治的(a+political政治的) anemia 反常的(a+nomal正常的+ous) ② 加在单词前,表示"在…,…的" asleep 睡着的(

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

Android多媒体开发介绍(转)

Android多媒体开发介绍 转自:http://blog.csdn.net/reiliu/article/details/9060557 一.       多媒体架构 基于第三方PacketVideo公司的OpenCORE来实现,支持所有通用的音频/视频/静态图像格式,包括:MPEG4.H.264.MP3.AAC.AMR.JPG.PNG.GIF等.从功能上分为两部分,一是音/视频的回放(PlayBack),二是音视频的纪录(Recorder). CODEC(编解码器)使用OpenMAX 1L

在iOS中创建静态库

如果你作为iOS开发者已经有一段时间,可能会有一套属于自己的类和工具函数,它们在你的大多数项目中被重用. 重用代码的最简单方法是简单的 拷贝/粘贴 源文件.然而,这种方法很快就会成为维护时的噩梦.因为每个app都有自己的一份代码副本,你很难在修复bug或者升级时保证所有副本的同步. 这就是静态库要拯救你的.一个静态库是若干个类,函数,定义和资源的包装,你可以将其打包并很容易的在项目之间共享. 在本教程中,你将用两种方法亲手创建你自己的通用静态库. 为了获得最佳效果,你应该熟悉Objective-

Swift备忘录

Swift 备忘录 2015-4 一.简介 1.Swift 语言由苹果公司在2010年7月开始设计,在 2014 年6月推出,在 2015 年 12 月 3 日开源 2.特点(官方): (1)苹果宣称 Swift 的特点是:快速.现代.安全.互动,而且明显优于 Objective-C 语言 (2)可以使用现有的 Cocoa 和 Cocoa Touch 框架 (3)Swift 取消了 Objective-C 的指针及其他不安全访问的使用 (4)舍弃 Objective-C 早期应用 Smallta