火星人的耳机(Martian Headsets)
非原创,来源网络,英文版原文: http://www.joelonsoftware.com/items/2008/03/17.html
![](/images/cnblogs_com/justinyoung/common/music_en.gif)
火星人的耳机
你们就要看到由web开发者挑起的网上“口水仗之母”了。它会让斯大林格勒战役看起来就好像是你的嫂子在下午茶时分冒着暴雨出门去你祖母家并把野马拴在树上一样。
这场即将到来的战役将由微软老兵Dean Hachamovitch挂帅。他正带队开发Internet Explorer的下一版,8.0。IE 8团队现在正在做一个决定,这个决定完美地,恰好地,精确地处在两种世界观的中间断层线上。这是保守者和变革者的分歧,这是“理想主义者”和“现实主义者”的分歧,这是一场巨大的划分家庭成员、工程师和计算机科学家以及凌志车和橄榄树的全球圣战。
而没有解决的办法。但它真的真的极富观赏性,因为99%的口水仗参与者不会去理解他们正在谈论的东西。这不仅仅是娱乐:对于每个需要设计交互式系统的开发者来说这是必读的。
这场口水仗将围绕所谓的“web标准”问题展开。我会让Dean来介绍一下这个问题:
所有的浏览器都有一个“标准”模式,称作“标准模式”,来提供浏览器对web标准的最尽力的实现。每个浏览器的每个版本都有它自己的标准模式,因为每个浏览器的每个版本都在提高对web标准的支持度。有Safari 3的标准模式,Firefox 2的标准模式,IE6的标准模式,IE7的标准模式,并且它们都不一样。我们想使IE8的标准模式比IE7的标准模式好得多得多。
整个问题取决于那个小小的决策:当IE8遇到一个声称支持“标准”,但可能只在IE7上测试过的网页时,它该怎么做。
标准究竟是什么玩意儿?
在各种各样的工程事业中难道没有标准吗?(不,有标准。)
难道这些标准都不起作用吗?(呃……)
为什么“web标准”这么混乱?(这不是微软一家的错。这也是你的错。还有Jon Postel(1943-1998),稍后解释)
没法儿弄。所有的解决办法都是错误的。Eric Bangeman在ars technica中写道,“IE团队不得不沿着一条羊肠小道,在支持W3C标准和确保现有的网站继续有效之间的小道中前进。”这句话说的不对。这不是一条羊肠小道。这是一条宽度是负数的道路。没有落脚的地方。无论他们做什么或是什么也不做,都会被人痛骂。
这就是为什么在这个问题上我没法选边站的原因,以后也不会。但是每个正在从业的软件开发者都应该至少理解,标准是如何生效的,标准应该如何生效,我们是怎么落到今天这个地步的,所以我想在这里试着解释一点这个问题,你会看到正是由于同样的原因,Microsoft Vista卖得这么清淡,而且这和我以前谈过 的两阵营是同一个问题:Microsoft的Raymond Chen阵营(实用主义者)对MSDN阵营(理想主义者),MSDN阵营正在取胜,所以现在没有人能够知道他们最喜欢的菜单命令在Microsoft Office 2007里都跑哪儿去了,且没人要Vista。而这里则是一场相同的辩论:你是一个理想主义者(“红方”)还是一个实用主义者(“蓝方”)。
让我从头说起。让我们从思考如何让不同的东西搭配工作开始。
什么样的东西?随便一样,真的。铅笔和削笔器。电话机和电话系统。HTML网页和web浏览器。Windows用户界面程序和Windows操作系统。Facebook和Facebook应用程序。立体声耳机和立体声。
在两样东西的接合点,要遵守好多规则,不然配合不起来。
我来举个简单的例子。想象你去了火星,在那里你发现火星人没有便携式音乐播放器。他们还在用大喇叭。你意识到这是一个巨大的商机,开始卖便携式MP3(在火星上它们叫Qxyzrhjjjjukltks)和兼容的耳机。为了连接MP3和耳机,你发明了一个灵巧的插头,就像这样的:
因为你控制着播放器和耳机,你能保证你的播放器与耳机相配。这是个一对一市场。一种播放器,一种耳机。
也许你写了一个规范,希望第三方会制造不同颜色的耳机,因为火星人很挑剔塞在他们耳朵里的东西的颜色。
在你写规范的时候,你忘了说明电压应该是1.4伏左右。你只是忘了。所以第一家积极的制造商生产的100%兼容的耳机问世了,他的喇叭只设计为0.014伏,当他测试原型的时候,要么爆掉耳机,要么震聋人的耳朵,看哪一件先发生。然后他做了些调整,逐渐地做好了一个好耳机,只是比你的稍微难看一点。
越来越多的制造商展示兼容耳机,不久我们处在了一个一对多的市场。
到目前为止,情况还不错。我们有了一个耳机插头的事实标准。那个写好的规范并不完整,也不适当。但是任何想要生产兼容耳机的人都可以把耳机插头插到你的播放器里去测试,如果配合良好,一切都好,他们可以卖了,而且肯定可以用。直到你决定搞个新版本,Qxyzrhjjjjukltk 2.0。
Qxyzrhjjjjukltk 2.0将附带一个电话(说明火星人也不能设计他们自己的手机),耳机将有一个内置的麦克风,这要求多一段触头,因此你重做了一个完全不兼容的插头,样子难看,有各种各样的扩展口:
Qxyzrhjjjjukltk 2.0在市场上完败。是的,它有非常不错的电话功能,但是没人在乎它。他们在乎的是自己大量的耳机收藏。我之前说火星人很挑剔塞在他们耳朵里的耳机,不是玩笑。大多数时尚的火星人在此刻有一整柜子各种各样漂亮的耳机。他们在你看来都一样(红色的),但火星人就是非常非常讲究红色的那种细微变化,这是你所永远无法想象的。最新的火星高级公寓都要标榜自己有一个耳机柜。我不骗你。
我们的新家伙不那么成功,而你迅速设计了一个新款:
注意,你在插头上多分了一段触头来处理麦克风信号,但麻烦的是,你的Qxyzrhjjjjukltk 2.1并不知道插进来的耳机是否有个麦克风,它需要知道这个信息才能决定是否启动电话功能。因此你发明了一个小协议……新设备在麦克风针脚上输出一个信号,在地线针脚上检测这个信号,如果有,它一定是3段式插头。否则说明没有麦克风,于是你会进入到兼容模式,只播放音乐。很简单,但这是一个协议磋商。
现在已经不再是一个一对多的市场了。所有的立体声设备由一个厂家制造,一个版本接着另一个版本,因此我要称之为系列对多的市场:
下面是一些你已经知道的系列对多的市场:
- Facebook | 约 20,000 个Facebook 应用
- Windows | 约 1,000,000 个Windows 应用
- Microsoft Word | 约 1,000,000,000 份Word文档
还有几百个其他的例子。要记住的是,当左手边的设备的新版本发布时,它必须保持自动向后兼容所有右手边的老的附件,因为那些老的附件在设计的时候可能不会考虑要连接新设备。火星人的耳机已经造出来了。你不可能回去把它们都改了。相比之下,改变新发明的设备以使其在连接旧耳机时表现得像个旧设备,要容易得多,也更合常理
因为你想要进步,增加新的特性和功能,你也需要一个新的协议让新的设备使用,合乎常理的做法是让两种设备在一开始时协商一下来确定它们是否都理解最新的协议。微软是在系列对多的世界里成长起来的。但还有一个多对多市场。
又过了好多年;你还在像疯子一样卖Qxyzrhjjjjukltk;但如今市场上有很多克隆的Qxyzrhjjjjukltk,比如开放源码的FireQx,还有很多耳机,你不断地发明需要改变耳机插头的新特性。这使得耳机制造商快发疯了,因为他们必须在每一种克隆Qxyzrhjjjjukltk上测试他们的新设计,这又耗时又费钱。并且老实说,他们中的大多数没有时间,只是在最流行的 MP3 5.0 上测过。如果测试通过,他们就很高兴。但是,当然了,当你把耳机插到 FireQx 3.0 时,它在你手里炸了,只是因为轻微地误解了规范里一段晦涩的、没人真正明白的内容,这段内容叫 hasLayout。人人都可以理解,当雨天时,hasLayout属性是true,电压会提高以支持挡风玻璃雨刷特性,但是对冰雹和下雪天是否也作为雨天来启用haslayout似乎存在一些争论,因为规范里没有说。FireQx 3.0 把雪天也当作雨天,因为下雪的时候你也需要雨刷,Qxyzrhjjjjukltk 5.0不这样,因为开发这个特性的开发员生活在火星上一个温暖的不下雪的地区,也没有驾照。是的,他们在火星上没有驾照。
最终一些讨厌鬼在他们的blog上写了一些长篇大作,详细解释了一个技巧,你能利用它来使Qxyzrhjjjjukltk 5.0表现得像FireQx 3.0一样。这个技巧利用了 MP3 5.0 里的一个高级bug来欺骗Qxyzrhjjjjukltk:通过融化一点点雪,让它在下雪的时候也以为是下雨。这很荒谬。但人人都在这么做,因为他们必须解决 hasLayout的不兼容。后来,Qxyzrhjjjjukltk团队在6.0中修正了这个bug,你再一次抓狂,你不得不去找某个可利用的新的bug来让装备了风挡雨刷特性的耳机可以适用于这两种设备。
现在。这就是多对多市场。左边有许多播放器各不相同,右边有数以亿计的耳机。两边都在犯错误,因为是人总会犯错。
不用说,这就是我们在面对HTML时的相同处境。几十种通用浏览器,亿万网页。
多年来,在多对多市场上发生的事情,就是呼吁“标准”,这样“所有的播放器”(特别是那些小播放器)都有同样的机会可以去正确显示所有8亿个网页,更重要的是,那8亿个网页的设计者们只需在一个浏览器上测试,只要遵照“web标准”,他们的网页在其它的浏览器上也能行,而无需在每个浏览器上测试每个网页。
看到了吧,想法就是,不是多对多的去测试,而是多对标准,标准对多的去测试,你的测试少了可不止一点点。更不要说,你的网页再也不需要任何针对特定浏览器的代码去解决不同浏览器的bug,因为在这个理想世界里,没有bug。那就是理想。
实际上,web还有点小问题:没法去对照标准测试一个网页,因为没有任何参考实现(Reference Implementation)来保证,如果它没问题,所有的浏览器都没问题。就是不存在这样的参考实现。
所以面对一堆你没读过的,或者读了也不能完全理解的标准文档,你只能去用你的头脑去“测试”,纯粹作为一种思维实验罢了。
那些文档超级难懂。文档里充满了诸如这样的句子:“如果一个兄弟块框(它不漂浮且不是绝对定位的)跟着一个插入框,插入框将变成块框的第一个行内框。一个插入框不能插入另一个块,如果那个块已经以一个插入框开始或是它自己就是一个插入框。”每当我读到这样的句子,我纳闷,怎么有人能以正确的遵从规范。
没有可行的方法来检查你刚写好的网页是否符合规范。是有些校验器(Validator),但它们不会告诉你这个网页会被如何显示,一个把所有的文字叠在一起看不清的,但是却是“有效的”网页也没什么用处。人们所做的只是针对某个或某两个浏览器去检查,直到它看起来正常。假如他们犯了一个错,但是在IE和Firefox里看起来没问题,他们也不会知道自己犯了错。当新出来一个浏览器/或版本时,他们的页面可能就看不了了。
如果你曾经访问过耶路撒冷最传统的犹太人社区,那里所有的人都完全同意并严格遵守犹太法里的每个字词标点,你会发现除了对哪些是干净的食物有一般的规定之外,你并不会看到一个来自某个传统社区的祭司会希望在另一个传统社区的某位祭司家里吃东西。而web设计者们正在发现Mea Shearim的犹太人几十年前就知道了的道理:不会仅仅因为你们都同意一本书就能保证兼容性,因为法律是如此复杂,难懂,绕圈,几乎不可能对它们有足够的理解以避开陷阱和地雷,你还是直接要水果盘吧,比较安全。
当然,标准是一个伟大的目标,不过在你变成一个标准迷之前,你必须要理解,由于人类的弱点,标准有时会被错误地解释,有时会令人困惑,甚至模棱两可。
这里真正的问题是,你在假设,有一个标准,但是由于没有人有一个方法去对照标准进行测试,这不是一个真正的标准:它是一种柏拉图式的理想和一系列的误解,因此标准并不能如人民希望的那样减少在多对多市场上的测试矩阵。
DOCTYPE是一个神话!
一个web设计者挂了一个DOCTYPE标签到他的网页上,说,“这是标准的HTML”,这是一种很傲慢的举止。但他们不会知道。他们要说的只不过是这个网页应该是一个标准的HTML而已。他们所真正知道的只不过是他们已经在IE、Firefox,也许还有Opera和Safari上测试过,看起来正常而已。或者是,他们从一本书上把DOCTYPE标签拷出来,却并不知道这意味着什么。
在真实世界里,人们不是完美的,你不可能只用一个规范就建立一个标准——你必须有一个超级严格的参考实现,每个人都只对照这个参考实现去测试。要不然,你会得到17份不同的“标准”,或者一份也没有。
这就是Jon Postel在1981年引起的问题所在,那年他造了一个新词,健壮性原则:“严于律己,宽以待人”。他说要让协议牢靠地工作的最佳方法是,人人都非常非常小心的遵守规范,但同时对别人,如果他没有严格遵守规范,要极度宽容,只要你能体会出他的意思就行。
所以,从技术上说,要显示一段小字段落的方法是<p><small>, 但是很多人写成<small><p>,这从技术上来说是不对的,至于为什么,大多数web开发者也都不理解,而web浏览器原谅了这种写法,把文字变小,因为这显然是他们想要的。
现在,到处是充满了这些错误的网页,因为所有的老浏览器开发者们开发出了超级开明,友好,通融的浏览器,它们爱你,不在乎你是否犯了错误。这样就出现了大量的错误。Postel的“健壮性”原则并非真正可行。这个问题多年来都没人注意到。2001年,Marshall Rose最后写道:
跟直觉恰恰相反,Postel的健壮性原则(“严于律己,宽以待人”)常常导致部署出现问题。为什么?当一个新的实现最初发布时,它可能会碰到一些现有实现的一个子集。如果那些实现遵从健壮性原则,那么新实现中的错误很可能不会被察觉。新的实现接着会碰到一些流传不是很广泛的部署。好些新的实现重复着这个过程。渐渐地,不是那么正确的实现跑进那些比最初的实现要少些宽容的实现里。读者该知道接下来会发生些什么。
Jon Postel 理应为他对互联网的发明所做的巨大贡献而骄傲,实在是没有理由为他那非著名的健壮性原则而责怪他。1981年还是史前时期。要是你能告诉Postel,会有9千万未受训的人(而不是工程师),去创建网站,他们会干很多乱七八糟的事情,而某种被误导的慈善,使得早期的浏览器开发者接受了这些错误,总会显示这些网页,他就会明白,这是个错误的原则。而实际上,web标准理想主义者是对的。创建web的正确的方法,本应该是有一个非常非常严格的标准,每一个浏览器都应该明确指出你所有的错误,web开发者如果不知道如何“严谨地提交”,就不要去写到处出现的网页,除非知道怎么做。
但话说回来,如果真是那样,web就不会像它现在这样起飞。也许,我们还会用着由AT&T运营的巨大Lotus Notes网络。
该怎样会怎样能怎样。谁会在意。都已经这样了。我们无法改变过去,只能去改变未来。见鬼,即使是未来,我们能改变的也没多少。
如果你是Internet Explorer 8.0团队里的一名实用主义者,你的脑皮层里应该深深地烙有Raymond Chen的这些话。他写过一些Windows XP是如何无奈地去模拟老Windows版本里的一些bug行为的文章:
站在消费者的角度来看这个问题。你买了些软件,有X,有Y,还有Z。后来,你升级到Windows XP。你的电脑现在时不时死机。而软件Z根本用不了。你会告诉你朋友:“别升级到XP!经常死机。与软件Z也不兼容。”你会去调试你的系统以确定是软件X导致了死机,而软件Z用不了是因为它用了未公开的window消息吗?当然不会。你会去把XP退货了(你的X,Y,Z软件是几个月前买的,已经过了30天退货期了,你唯一可以退的是XP)。
你也在思考了吧,嗯? 让我们为这段话更新一下版本吧:
站在消费者的角度来看这个问题。你买了些软件,有X,有Y,还有Z。后来,你升级到Windows XPVista。你的电脑现在时不时死机。而软件Z根本用不了。你会告诉你朋友:“别升级到XPVista!经常死机。与软件Z也不兼容。”你会去调试你的系统以确定是软件X导致了死机,而软件Z用不了是因为它用了不安全的window消息吗?当然不会。你会去把XPVista退货了(你的X,Y,Z软件是几个月前买的,已经过了30天退货期了,你唯一可以退的是XPVista)。
微软内部理想主义者对实用主义者的胜利,我2004年就报道过了,直接解释了为什么Vista收到一片恶评,并且销售惨淡。
而这些话又是如何说到IE团队身上的呢?
站在消费者的角度来看这个问题。你每天访问100个网站。后来你升级到IE 8。一半的网页显示混乱,Google地图根本用不了。你会告诉你朋友:“别升级到IE 8! 所有的网页都显示得乱七八糟,Google地图根本用不了。”你会去查看源代码以确定X网站使用了非标准的HTML,而Google地图用不了是因为它使用了老版本IE里提供却从未被标准委员会接受的非标准JavaScript对象吗?当然不会。你会把IE 8卸了(那些网站不是你控制的,有些网页的开发者现在已经不在人世了。你唯一可以做的事情就是退回到IE 7)。
所以,如果你是IE 8团队的一个开发者,你首先要做到的是在系列到多市场上屡试不爽的事情。你们会做一些协议层的协商,对那些没有明确告诉你它们期待新行为的站点,继续模拟以前的行为,这样所有的现有网站继续可以用。你只会在那些在网页上写了一个小标记,说:“嗨!我与IE 8神交!来吧,请给我你的所有新货!”的时候,才会看到新行为。
实际上,那曾经是IE团队宣布的第一个决定,时间是1月21日。浏览器会自动考虑到现有网页,人们不必去修改网站以使它们能像在旧版本的、bug多多的被web开发者痛恨的IE 7里的那样。
一个实用主义的工程师会下结论,说IE团队的最初决定是正确的。但年轻的理想主义者“标准”人们受不了了。
他们说,IE需要提供一个web标准体验,而不必要求写一个特殊的“嗨!我已经在IE 8下测试过了”标签。他们对特殊标签感到恶心。所有这些该死的网页不得不写37个丑陋的hack以使它能够在5到6个流行的浏览器里可用。受够了这些丑陋的hacks!8亿个现有的网页,下地狱吧!
IE 团队掷了硬币。他们的第二个决定,我必须认为这不是最后的决定,是去做理想主义者的事。对所有声明“标准兼容”的网页,都认为它们是为IE 8设计的,并已经测试过了。
在我用IE 8访问过的几乎所有网站,都会有某种形式的失效。用了大量JavaScript的网页一般来说都彻底死翘。大量的网页只是有显示上的问题:比如内容跑到别的地方了,弹出菜单的中间会有个滚动条压着。有些站点有些更微妙的问题:它们看起来还行,但你点着点着,一些关键的表单却提交不了了,或直接跑到了一个空白页。
这些并不是有错误的网页,它们通常是遵照web标准精心构建的网站。但由于IE 6, IE 7并非真正符合规范,因此那些网站里有一些hacks,比如说“在Internet Explorer上……把这个东西向右移17像素以补偿IE的bug”。
而IE 8还是叫IE。但已经没有了IE 7的bug,他们遵照规范把那个曾经左偏17像素的东西移了。所以现在,那些曾经的补偿都没用了。
IE 8无法正常显示大多数网页,直到你放弃,单击那个“像IE7那样做”的按钮。理想主义者不在乎这些,他们要的就是让你去改那些网页。
那些网页中的一部分已经没法改了。它们可能刻在了CD-ROM上。它们的作者现在已经不在人世了。大部分的网页都是那些现在不知所措的人创建的,为什么这些网页,4年前花钱雇一个设计师开发的网页,现在看不了了呢?
理想主义者欢欣鼓舞,他们去IE团队的blog上,有生以来第一次为微软说了好话。我看着我的表。滴答,滴答,滴答。几秒钟内,你开始看到有人在论坛上这么发贴:
我下载了IE 8,有些bug。我的一些网站,比如"HP",读起来非常困难,因为页面变得非常非常小……我的网速也时不时会慢一下,我去google地图,页面上到处都是重叠的东西,真难用!
嗯。你们这些沾沾自喜的理想主义者,嘲笑这只菜鸟。顾客不是傻子。她是你妻子。不要嘲笑了,98%的人会装IE 8,然后说“有bug,我看不了我的网页。”他们不会为了你们这些愚蠢的对开发一个合乎有点神话般的,柏拉图式的规范的浏览器有着宗教般狂热的人打响指。而这个标准并没有在任何一个地方被实现过。理想主义者不想听你们讲那些肮脏的hacks。他们只希望web浏览器只接受真正的网站。
看到了吧,这是个多么可怕的例子,说明了两个阵营之间的鸿沟。
web标准阵营看起来是左翼的。但你要真的开发了一个网页,声称符合标准,而事实上却不是,理想主义者就会变身为美国最严厉的州长Joe Arpaio:“你犯错了,活该你的网站看不了。我不在乎你的80%的网页都看不了了,我会把你们全都关进监狱。在那里你们会穿上粉红色的囚裤,吃15分钱的三明治,排队干活。而且我并不在乎把整个郡的人都扔进监狱。法律就是法律。”
另一方面,我们有实用主义者、敏感的、热心的、温柔的工程类型。“我们不能默认为IE 7模式吗?只用1行代码……打包!解决!”
是秘密吗?这就是我思考的会发生的事情。IE 8团队会告诉每个人IE 8默认会使web标准,在漫长的beta测试期内,他们会请求人们在IE 8里测试他们的网页,并让它们正确运行。当他们临近发布时,世界上只有32%的网页可以正确显示。
他们会说,“看,伙计们!我们真的很抱歉,我们真的想让IE 8默认使用web标准模式。但我们没法发布一个不能用的浏览器。”他们会回到实用主义者的决定上来。也许他们不会,因为实用主义者离开微软权力层已经有些时日了。如果是这样,IE 会失去很多市场份额。但理想主义者会雀跃,或许Dean Hachamovitch的年终巨奖也不会少一分钱。
看到了吗?没有正确答案。
通常,理想主义者在道理上是100%的正确;通常,实用主义者在现实里正确。口水仗会持续数年。这场争论把世界分成两半。如果你有办法可以买到互联网口水仗的股票,现在是一个不错的入市时机。