逐步改善,设计优秀的API( 二 )


二进制字节码的格式与Java源代码的格式非常相似 , 这有好的方面 , 也有坏的一面 。说它好 , 是因为这样的格式很容易理解 。说它坏 , 是因为它会引发一些误解 。但大家应该记住 , 在编写API的时候 , 只有通过二进制格式才能最终判断不同版本的API是否兼容 , 也就是说代码执行时的兼容性才是最根本的 。所以一定要了解Java源代码是编译成何种样子的字节码 。如果有疑问的话 , 最好反编译一下Class文件 , 检查一下到底是不是自己期望的样子 。有可能你会为反编译的结果大吃一惊!
功能兼容——阿米巴变形虫效应
如果一个类库在运行时 , 不管所引用的是老版本还是新版本的类库 , 其产生的结果完全相同 , 那么这两个版本可以称为功能兼容 。这个定义看起来简单 , 但背后的含义却不简单 。
作为开发人员 , 你可能会清楚地知道你所开发类库都提供了哪些功能 , 假设你提供了优秀的规范和完善的文档还有其他的信息 , 从而能够清楚地对类库的功能加以说明 。当然这只是一个假设 , 从来都没有什么优秀的文档可以做到上面所说的目标 。在现实世界中 , 文档总是比程序慢上一步 , 而且其描述的信息也只是整个程序的一部分内容 。但还是先假设有一些开发人员已经完美地分析了程序 , 并清楚地知道程序的所有功能 。如图 1中所描绘的那样 。

逐步改善,设计优秀的API

文章插图

逐步改善,设计优秀的API

文章插图
但大家都很清楚地知道软件开发中的一条金科玉律:每个程序至少都有一个Bug 。什么意思呢?所谓的Bug其实就是程序的功能不符合预期定义的内容 。即使开发人员愿意相信程序的行为如图1中定义的那样完美 , 而现实中 , 程序的功能与其预期定义的内容都是存在出入的 。在特定情况下 , 代码并没有实现预期的功能 , 而在其他情况下 , 所完成的功能要超出预期 。如图2所展示的样 。
逐步改善,设计优秀的API

文章插图
问题就隐藏在这张图的背后!假设这张图同时描述了现实世界与理想世界中的程序功能 。那么圆是一个清楚的功能定义 , 而具体程序则有所出入 , 有时没有完成规范中定义的某些功能 , 有时却又超出了规范中定义的某些功能 。而程序员在开发代码时 , 往往不会去阅读相应的规范 。事实上 , 几乎没有哪个开发人员会去读这些API的规范 , 直到出现严重的问题 。他们会用“编码/运行”这样的方式来完成自己的工作 。比如说开发人员写了一些代码 , 运行之后发现完成了自己需要的功能 。此时 , 他们关注的是那些API背后具体实现所完成的功能 , 并不关心规范怎么说 。这样做 , 其实是让代码依赖于具体的实现 , 而这些实现内容并不会写到规范中 。显然 , 不管是少提供了功能 , 还是多提供了功能 , 这两种情况都是非常危险的 , 会影响到未来类库版本的共存 , 更会影响使用这些类库的程序 。一旦该类库有新版本发布 , 修正了某些bug , 或者再添加一些功能 , 都有可能会影响你的程序 , 就像图3一样 , 从圆变成了不规则形状 。