为什么说市场上现有的设计图书还不够用呢?这是因为设计框架或者通用类库是一件非常复杂的事情,其复杂度与自行设计内部系统不可同日而语。打个比方,在一台服务器上基于一个小型数据库来搭建一个Web应用之类的小系统,就和盖一间房子差不多。当然,有些房子可能很小,也有些房子会很大,有时也许是一座摩天大楼。这些建筑通常情况下都只有一个主人,只有他才会改造这个房子。如果需要的话,改一下屋顶,换上新窗户,也许会砌面墙多隔出一间来,再拆旧墙打通两个房间,等等。当然,有些改变算不上什么麻烦事,如换个屋顶不会对地板造成什么大的破坏,换个窗户,只要大小规格不变,也不会影响别的部位。但是,如果想把窗户从小变大,就不那么简单了,而想换个两倍大的新电梯更是不可能完成的任务。再如,罕有人会疯狂到盖个新的一楼,然后把原来的楼层都往上移一层。这样做实在是问题多多,弊大于利。当然,从技术角度来看,上面这些变化仍然是可行的。只要这个房间的主人确有这个需要,铁了心也能做到。 内部软件系统也有些相似。通常也只有一个所有者,而且它还具有完全的控制权。如果现在需要对系统中的部分功能进行升级,那么尽管放手去做就是了!如果要改变一下数据库的模式,也可以悉听尊便。当然,有些改变会比较复杂。拿以下两种情况作个比较:修改一行代码来修复一个NullPointerException的bug和调整数据库模式,显然,后者的影响会大得多。但对于内部系统来说,一切改变都是可行的。因为其所有者有着绝对的控制权,只要系统确实需要大的升级,甚至可以暂时关闭这个应用系统,等完成升级以后再重新运行。此外,我们已经有了不少相关的设计原则帮助,我们更好地管控一个内部系统的变化。有设计模式的书籍帮助开发人员更好地组织代码,还有不少关于设计系统和测试系统的方法论,还有大量的图书介绍如何组织和领导员工进行团队合作。可以说,维护一个内部系统的方方面面,都是非常清楚明了的,也有很多详细文档可供参考。 但是编写API则有所不同。可以拿宇宙来打个比方,尽管宇宙不像先前说的房子那么直观,但还算得上比较形象。先来回忆一下我们已知的宇宙,我说“已知”的宇宙,是因为没有人能洞悉宇宙的一切,所有那些恒星、银河,以及其他天体,还包括无形的内容,如所有物理规律。当然,人类现在对宇宙所了解的其实只算得上沧海一粟。我们的视野有多宽,就限定了宇宙在我们眼中的样子,也就是说,我们所说的宇宙,只是在我们自己眼中的宇宙,是真实宇宙在我们眼中的一个缩影。它包含了无数的天体和状态,然而,我们的经验和想象告诉我们,在我们视野范围以外,还有其他的星星和银河,但我们对它们一无所知。千百年来,人类通过打造更先进的设备及不断地认识和理解自然的规律,不停地扩展自己的视野,不断地发现新事物或者新规律,人类关于宇宙的认识和经验就是基于上述实践而逐渐形成的。 宇宙并非亘古不变,而是时刻都在变化,但其变化却有规律可循。这些规律告诉我们,行星、恒星以及其他天体之间是如何相互影响的。举例来说,假设某个人通过自己的观察,发现了一颗新的恒星,那么不管明天、后天还是大后天,都可以观察到这颗恒星,这并不奇怪。虽然现有的自然规律告诉我们:恒星不仅会移动,而且会旋转,甚至还会爆炸。但这些变化都会遵从自然规律。不会有人隔一两周就发现一件宇宙大事,说有某个恒星出现了,消失了,或者是进行随机性的移动。如果宇宙真有这么疯狂,那么就完全颠覆了我们今天对于宇宙的认识。我们通常认为,一旦一颗恒星被发现,它就会长久存在,甚至相信即使无人观察到它,它依然存在。这颗恒星可以被地球上的一个人观察到,也可以被太阳系其他地方的另外一个人观察到,甚至还有宇宙中其他智慧生物观察到,当然也可能无人注意它。但恒星本身并不知道自己是否被他人所观察,它只会默默遵照自然规律存在和运行。因此一旦被发现,它便一直陪伴着我们。 好的API也是如此。一旦某个通用的类库在某个版本引入了一个新方法,就好像发现了一颗新的恒星。所有使用该类库的人都可以看到并使用该方法。至于是否在自己的程序中使用,则要视乎程序员自己的需要了。有可能,多数API的使用者对你添加的新方法完全不在意。但你不能把希望寄托在这种并无根据的猜测之上。多年的开发经验告诉我,API的用户太有创意了。有时候,他们涉及的领域甚至超过了API设计者。换句话说,只要API有可能被误用,就一定会有人去误用这个API。随之而来的结果就是,不管是方法本身还是其设计者,都不知道该方法是否被使用及其使用频率有多大。也许会有很多用户使用它,也许一个都没有,但除非你想破坏优秀API的设计法则,即打破其向后兼容性,否则就必须假定有人在观察,必须保证这些API得到良好的维护和保留。“API就如同恒星,一旦出现,便与我们永恒共存。” 宇宙与API的设计还有一个相似之处。我们对宇宙的认识不断加深,正如我们的类库在不断演进。古希腊人已经可以识别和观察远至土星和木星的所有行星的运行路线,这就是他们眼中的宇宙的样子。他们尽力去解释行星运行背后的原因,但以今天的标准来看,他们显然并不成功。他们还不能揭示出行星运行的规律。到了文艺复兴时期,哥白尼提出了日心说,而开普勒则用行星三大定律来诠释行星相对于太阳的运行轨迹和速度。这些探索丰富了人类对宇宙的发现,从而能够对“宇宙是什么”进行精确的解释。但没有人知道“宇宙为什么是这个样子”。直到1687年,牛顿才对这个问题给出了诠释,他引入了万有引力的概念。万有引力不仅可以用来解释开普勒定律,还极大地扩展了我们对宇宙的认识,因为对于已知宇宙中多个天体间发生的所有事情,基于牛顿定律的物理学①几乎都可以给出合理的解释。 一切看来都很完美,直到19世纪末。很多实验都发现了一些无法用牛顿定律来解释的现象,特别是对于一些高速运动的天体。这些现象促使爱因斯坦创立了相对论,帮助我们更深入地理解宇宙及其各种现象包括对高速运动的天体的理解。事实上,爱因斯坦的理论是牛顿理论的延伸,只要天体慢到一个合理的速度,那么使用这两个理论可以得到相同的结果,此时可谓殊途同归。 前文啰哩啰嗦地说了很多物理和历史背景的内容,这些东西与设计API有半点关系吗?接下来先让我们来假设有一个上帝,万能的他通过一个API库与人类进行沟通。这个库是人类通向这个已知的宇宙的桥梁。古希腊人使用这个库的0.1版本,其功能很简单,只能用来列举不同的行星以及它们的名字。这个库提供的API显然不够丰富,但对于那时候的人来说,已经足够了。借助于这个简单的API库,古希腊人已经可以分辨几颗行星。在这个库的使用过程中会有不少人经常提出新的需求,希望对这个API库加以改进。当开普勒需要进一步了解行星的运行规律时,就发现这个库的功能已经不能满足他的需要了。因此,这个万能的上帝就给了他一个升级版本,姑且称之为1.0版吧。这个版本的库能够为每个行星在某个时间点上提供空间坐标,以确定其位置。同时1.0版本很好地兼容了0.1版本,也就是说,原来那些古希腊人所使用的功能仍然可以正常使用。 只不过,用户从来没有知足的时候,物理学家们亦如是。为了帮助牛顿,那位万能的上帝接着提供了宇宙2.0这个重要的版本。该版本不仅描述了太阳和其他行星之间存在的万有引力,还提供了一堆公式用以计算空间物体的引力、加速度及速度,也不再只局限于行星了。不用说,这个新版本仍然兼容以前的版本,古希腊人和开普勒使用的那些功能仍然可以在新版本中正常使用。 至此,所有的变化都很直接。一直以来,那位万能的上帝只是为新版本添加了一些功能。在经典物理学成熟以后,物理学家声称,宇宙的所有规律都已经被物理学家发现了,在物理学的领域已经没有什么未解之谜了!这个声明真是一个天大的讽刺,上帝抛出了迈克尔逊实验②证明了这个臆断的荒谬,进而导致爱因斯坦提出他的相对论。这时候,物理学家们发现,最新版本的宇宙API库出现了无法简单向后兼容的问题,因为新的理论指出,以前所有的物理学家,包括牛顿,都存在少许的错误!尽管出现了如此大的一个变动,但新的API库仍然可以按向后兼容方式来处理。那是因为只有以特别高速运动的物体,根据原有方式来计算得到的结果才有可能不正确。而在牛顿及其先行者的那个时代,受限于技术等原因,是无法对这样高的运动速度进行测量的。因此,尽管不兼容的问题早就存在,但用以前的测量技术却发现不了,从而也无法证实宇宙API库的功能发生了改变。 上述这个荒诞的故事旨在说明我们对宇宙的认识一直在不停地进步。我们编写的API库也同样如此。或许乐观的人并不认同,但我真的感觉人类永远都无法了解整个宇宙的奥秘。当然,我认为我们对宇宙的了解会越来越多。虽然程序员的观点各有不同,但我相信所有已经在使用的API库都会永无止境,它们会继续演化。对此,我们必须做好准备。我们必须准备好随时改进我们的API库,就像我们必须准备好随时修正我们对宇宙的认识。 与建造一所房子或一个内部的软件系统不同,编写API库需要开发人员放眼未来,看到今后潜在的需求。但在我看来,现在人们设计API的做法往往不是这样。目前市面上的图书也并没有促使人们这样思考。书中的设计模式大多只能用在特定版本,使用者也只是在特定上下文的环境中去考虑问题,他们极少参考老的版本,也不太考虑未来的需求,所举的例子以及相关的上下文都具有很大的片面性。当然并非说这些书全无裨益,在编写通用功能库和框架时还是需要这些技巧。现在,我们必须停止学习如何来设计内部系统,而要开始学习如何来设计一套API库。在学习中一定要坚持一个观点:“API一旦发布,便与我们永恒共存。” ① 指的是经典物理学。——译者注 ② 迈克尔逊干涉仪是1880年美国物理学家迈克尔逊为研究“以太”漂移速度实验设计制造出来的。1887年,他和美国物理学家莫雷合作进一步用实验结果否定了“以太”的存在,为爱因斯坦建立狭义相对论开辟了道路。由于发明了精密的光学仪器和借助这些仪器所做的基本度量学研究,迈克尔逊于1907年获得了诺贝尔物理学奖。 ——译者注
软件框架设计的艺术——API设计的特殊所在
书名: 软件框架设计的艺术
作者: [捷克] Jaroslav Tulach
出版社: 人民邮电出版社
原作名: Practical API Design: Confessions of a Java Framework Architect
译者: 王磊 | 朱兴
出版年: 2011-3
页数: 388
定价: 75.00元
装帧: 平装
丛书: 图灵程序设计丛书
ISBN: 9787115248497