评判浏览器API好坏的标准是什么
Original Post:What makes a good browser API?
Nicholas C. Zakas,2009年11月24日
翻译完成:2010年1月22日,最后更新:2010年1月22日
上个月,我又参加了Mozilla公司组织的一次研讨会,这一次讨论的是Web数据库。虽然研讨会的议题很有意思,但我觉得会议期间大家对另一个问题的争论似乎更值得关注。争论中,与会者针对浏览器到底应该为JavaScript提供什么样的API分成两派。一派坚持认为原生的JavaScript API应该尽量保持低级化,然后由库开发者在低级API基础上再去构建更好用的接口。另外一派,也是我所在的阵营,则认为中级API才是大势所趋。没有人认为浏览器应该向开发人员提供高级API。所谓低级、中级、高级到底都是什么意思呢?
低级API
低级API仅为提供基本功能而设计。由于只要能实现相应功能即可,因此这种API不需要很直观或者很好理解。有时候,低级API确实会给初级甚至中级开发人员造成理解上的困难。这样一来,借由人们频繁使用来发现相应API问题的机会就大为减少了。大家都会指望库开发者在这些低级API基础上实现直观、好用的API,以便于普通开发人员使用。doument.cookie就是说明低级API最好的一个例子。
作为JavaScript开发人员操作cookie的唯一接口,document.cookie可谓有史以来最难使用的一个API。关于cookie,我专门写过一篇文章,还探讨过它的安全性问题,其中都涉及到如何在JavaScript中使用它们;因此,这里只能算是一个简单的介绍了。要设置cookie,必须以正确的cookie格式来设置document.cookie属性,例如:
document.cookie = “name=Nicholas; domain=nczonline.net; path=/; expires=Sat, 02 May 2009 23:38:25 GMT
要取得cookie,则需要读取document.cookie,返回的字符串是如下列所示的名值对格式:
name1=value1; name2=value2; name3=value3; name4=value4
而为了得到想要的值,必须先从这个字符串中查找相应的名字,然后再解析出相应的值。
之所以把这种API归类为低级API,是因为其实现要求你必须先了解cookie的内部格式,然后才能使用它。实际上,document.cookie属性只是在简单地模仿Set-Cookie和Cookie这两个对开发人员不可见的HTTP首部。为了写cookie,必须要理解字符串的确切格式,这涉及到其中的名和值必须采用URI编码形式,而其他片段之间必须以一个分号和一个空格来分隔,此外还必须知道设置过期日期的正确日期格式。反过来也一样,在读cookie时,你同样需要知道返回的字符串是什么格式,然后才能从中解析出想要的数据。这就是所谓的“遇繁不简,遇简也不简”。一句话,这种API对于不了解cookie的人根本没有用。
如果大多数开发人员都不会直接使用某个API,你就可以说它是低级API。不用,是因为使用它们所需的知识储备(Cognitive Overhead)太多了。绝大多数开发人员在使用JavaScript读写cookie时,最终都会求诸于一个JavaScript库例如YUI中的Cookie工具(YUI2和YUI3),这些工具把那些令人讨厌的实现细节都隐藏起来了。
这正是那些低级API的支持者所愿意看到的:浏览器应该只提供基本功能,而基于这些功能开发易用API的任务应该交给开发人员社区。这些人支持低级API有一个主要的理由,即围绕基本功能可以实现任何层次的抽象,开发人员也会因此获得更多选择,从而更好地利用基本功能。
低级API的问题在于浪费时间。如果你创建了低级API,那结果就是潜在用户的数量会很少。至于什么时候能够出现好用的抽象工具,只能指望某一天这些用户中有(一个或几个)人会意识到确实有必要去做这件事,以便其他社区人员更好地利用该API。如果你想让新API尽快地被别人使用,你就会明白应该怎样去改进它,低级API根本不合适。
提示:大多数服务器端语言(如 ASP.NET、JSP、PHP)都提供了读写cookie的原生抽象,但JavaScript始终都没有。
高级API
这一争论的另一个极端是高级API。高级API设计出来就是为了让开发人员直接使用的,并且一般都非常直观。这种API不仅要考虑提供某种功能,而且还要提供使用相应功能的友好、易用的接口。高级API设计首先考虑的是开发人员的方便,因而通常需要对开发人员使用API的方式从理论上作出归纳。显然,这又是一个问题:谁能确切地知道某个人希望怎么去使用一个API呢?因此,在浏览器中提供原生的高级API几乎就是一个不可能完成的任务。
各式各样的JavaScript库就是高级API的典型例子。这些库都面向相同的浏览器,但为实现相同功能而提供的接口却差别很大。使用jQuery的方式与使用YUI截然不同;这是件好事,因为开发人员可以选择。可是,如果你告诉YUI开发人员必须使用jQuery语法写代码――因为只能使用一种语法;或者相反,会怎么样呢?相信对此提出抗议的开发人员一定会成群结队。强迫人们必须以某种方式开发是不幸之源。只有抽象,或者说只有随时都可以提高和降低抽象级别,才会让开发充满乐趣,也才能激励开发人员不断地创新。
高级API要求的知识储备非常低,因此开发人员无需了解太多就可以直接使用。但值得高兴的是,没有人认为浏览器应该提供高级AIP。大家都希望有所选择,都希望不同程度的抽象。
中级API
折衷方案是中级API。以我的观点来看,中级API是浏览器所应该研究和实现的。顾名思义,中级API处于低级和高级之间,兼具二者之长。所谓中级API,(我的定义)就是针对最常见的应用提供简单的接口,同时能够通过扩展实现更强大的操作和对不常见应用的支持。第一部分,常用的接口,是非常简单、无需抽象即可直接使用的。而不常用接口可以更复杂一些,甚至可以“让人摸不着头脑”,因为很少会有人用。
XMLHttpRequest是不错的中级API中最出色的例子。使用它最常见的情形就是发送一次GET请求,然后取得XML数据。实现这个过程的代码不多:
var xhr = new XMLHttpRequest();
xhr.open(“get”, “/somexml”, true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status == 200){
process(xhr.responseXML.getElementsByTagName(“item”));
}
}
};
xhr.send(null);
虽然有人会说onreadystatechange这个事件处理程序看起来有点麻烦,但实际上,你要做的不过是检查一点信息,以确定是否接收到了正确的数据。可是,所有必需的信息都已经各就各位了,而且也已经转换成了方便访问的格式:HTTP状态就在那摆着,而XML也已经转换成了DOM格式。为了给你提供这些数据,API已经做了不少的工作了。
另一种不太常见的用法就是在URL中包含提交的表单数据。虽然代码难看点,但仍然可以接受:
var xhr = new XMLHttpRequest();
xhr.open(“post”, “/add”, true);
xhr.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status == 200){
signalComplete();
}
}
};
xhr.send(encodeURIComponent(name) + “=” + encodeURIComponent(value));
除此之外,你当然还可以把XMLHttpRequest对象用于更复杂的处理中,例如Comet。问题的关键在于,它在常用情形下很简单,而且还能轻易地支持更复杂、更不常见的用例。这样一来,JavaScript库也容易在后台构建一个比较好用的接口,帮我们处理那些复杂应用下的琐碎细节。尽管每个JavaScript库在如何发起Ajax通信方面各有各的方式,但XMLHttpRequest接口的设计能够很好地适应所有方式。
注意:有些人认为XMLHttpRequest也属于低级API。我承认它不是最清晰的API,但在常见用例中它确实非常简便易行。不要忘了,最初在设计这个对象的时候,常见用例就是从服务器上取得XML数据。从那个时候到现在,常见用例已经变了,但人们照样还在使用同一个API。在我看来,这恰恰表明了它是一个不可多得的中级API。
总结
我主张浏览器应该原生提供中级API,这样才能自如地应对常见用例,同时还可以为不常见的用例留下扩展的空间。API的抽象程度太低,不利于广泛流传,更不容易引起开发社区的重视;API的抽象程度太高,由于限制的用例太专,人们要么能用,要么根本就用不了。目前来看,较新的API似乎有低级化的倾向,如此一来,开发人员在实际使用它们之前,往往需要有第三方来实现一些必要的抽象。我希望能够阻止这种趋势,好让常见用例实现起来更简单,以便人们能够立即使用它们,同时还可以对它们加以扩展。而中级API能够同时满足这两个条件。
建议继续学习:
- 浏览器的工作原理:新式网络浏览器幕后揭秘 (阅读:19668)
- 浅析http协议、cookies和session机制、浏览器缓存 (阅读:15931)
- 从输入 URL 到页面加载完成的过程中都发生了什么事情? (阅读:14614)
- 好的API设计 (阅读:11346)
- 程序员眼里IE浏览器是什么样的 (阅读:6967)
- 浏览器的渲染原理简介 (阅读:6498)
- 各种浏览器审查、监听http头工具介绍 (阅读:6355)
- 图说浏览器战争:火狐、微软、谷歌那些事 (阅读:6191)
- 浏览器缓存机制 (阅读:5836)
- Google短网址的API (阅读:5203)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:为之漫笔 来源: 为之漫笔
- 标签: API 标准 浏览器
- 发布时间:2011-01-27 22:57:02
- [71] Twitter/微博客的学习摘要
- [68] IOS安全–浅谈关于IOS加固的几种方法
- [66] 如何拿下简短的域名
- [65] android 开发入门
- [64] find命令的一点注意事项
- [63] Go Reflect 性能
- [61] 流程管理与用户研究
- [61] Oracle MTS模式下 进程地址与会话信
- [59] 图书馆的世界纪录
- [58] 读书笔记-壹百度:百度十年千倍的29条法则