阅读者 (十四): 软件框架设计的艺术

  • 丁雪丰

2011 年 6 月 10 日

话题:JavaIDE架构Book Review语言 & 开发文化 & 方法

不知有多少人和我一样,对自己日常使用的开发框架和 IDE 的作者充满敬意,对它们的开发过程充满好奇。如果你也使用过 NetBeans,曾把它当作日常 IDE,那么你应该会对《软件框架设计的艺术》感兴趣,因为其中包含了 NetBeans 创始人 Jaroslav Tulach 在设计 NetBeans 过程中总结出来的经验教训,设计心得,同时,这也是 NetBeans 的一部备忘录。

首先,如果你还未阅读本书,或者还未购买本书,我希望你能够做好心理准备,本书并不是为初学者所准备的。俗话说的好,没有金刚钻别揽瓷器活,要是没有一些相关的实践经验,阅读本书会有一定的困难,至少会浪费你的时间和金钱。这里我所说的相关经验并不是简单地开发一些小型网站。开发一个框架或 API 和开发应用系统还是有很多不同的。

全书分为三个部分——理论与理由、设计实践与日常生活,阅读指南给出了一个很好的建议,如果你对那过于理论充满哲学论调的第一部分不感冒,不妨先从第二部分开始,之后再来阅读开头的理论部分。但我的建议还是按照顺序阅读吧,至少从一开始你就能知道我们和自己的前辈所处的环境不同,几何学是多么的纯粹,什么才是优雅的程序语言,为什么说现在的程序员中有一大部分是在“针对性无绪”(这里作者并没有贬低不深入了解很多内容也可以完成任务的意思),好歹你可以知道什么是 API,什么是 SPI,光这些知识就可以让你受益匪浅了。再不然,那张 Will Code HTML For Food 的插图也能博你一笑,不要把自己看得太高了。

“博学”一词似乎总与“大师”行影不离,不少人虽然从事 IT 行业,但却拥有艺术学位,有的在物理化学方面颇有造诣。Jaroslav 在序言中就用他的天体物理和历史知识将我折服了,通过那个恒星的比喻,让我对 API 的设计有了新的认识。

在设计实践部分中,你会读到很多技巧性的内容,有些是你了解的,有些是你知其然不知其所以然的,有些是你所未曾了解过的,更有一些是与你理解中的知识所冲突的……这也就是为什么说开发一个框架不同于开发一套应用系统。知道设计模式的人都可以说出如何实现工厂模式,但又有多少人可以说清楚工厂方法优于构造方法的?用过 Sonar 等类似工具的人都会知道,它们会提示你将一些类声明为 final 的,但你又可曾想过其中的原因?整天把“面向接口编程”挂在嘴边,那究竟什么是接口?不要狭义地认为这个接口就是 Java 中的 interface,它的含义远不局限于此,设计一个好的接口也是有讲究的。这些问题的答案都可以在设计实践部分里找到。

现在 Spring 基本成为了多数 Java 应用系统开发中的标配,谈及框架几乎必定会涉及到它,它把依赖的概念带给了大家,也提供了组件和服务等模块化的思想(当然和 OSGi 还是有所区别的)。在“模块化架构”一节中,Jaroslav 专门介绍了 NetBeans 的 Lookup 机制、Java 6 的 ServiceLoader 和 Spring 提供的依赖注入,可以让人更好地理解组件注入和服务定位,至少可以更好地理解 Spring 的依赖注入机制。本节还提及了扩展和扩展点,关于这个概念我在初次接触时也曾有过怀疑,真的很有用么,不用也挺好啊,但只有真的遇到了特定的场景才能体会到设计扩展点的用意,读到这段真的让我深有感触。

作为一本翻译的技术书籍,其翻译质量也会影响读者的阅读体验。我可以感受到译者在翻译过程中下了很大的功夫,从书中大量的译者注就可以体现出译者的敬业精神,甚至可以看得出他专门读过 NetBeans 的源码。但是书中的翻译确实称不上完美,也许和本书作者是捷克人多少有些关系,有些原文在翻译时可能不太好理解。但正所谓瑕不掩瑜,本书的内容丰富,对学习如何设计一个好的框架很有指导意义,有兴趣的读者不妨自己去品味一下。

——InfoQ 中文站 Ruby 社区编辑 丁雪丰


正如本书作者在序言中问到“仅仅是又多了一本设计书吗?”作者相信本书的存在“自有其必要性”,原因在于本书探讨的设计领域是如此的卓尔不群,却又是 Java 程序员在开发中必须要面对的问题,那就是框架的设计,API 的设计。

我自认为对面向对象设计的掌握已经深入骨髓,对设计模式也算得上了然于胸,可在阅读本书时,我才发现自己所知不过是米粒之珠,对象设计原来还有更加广阔的世界。API 设计的不同,已经超出了通常的面向对象设计讨论的范围。API 的演化需要考虑的因素,比起一般的接口与类的设计,要更加地复杂与困难。面向对象设计有一个非常重要的原则是“开放 - 封闭原则(OCP),利用抽象以应对扩展,利用封装以隐藏实现,从而避免修改。这是我们在设计中需要遵循的一条重要法则。但我始终认为,要达成真正的开放与封闭,实则是一种遥不可及的理想,在现实的开发过程中,能做到修改尽量少,扩展尽量容易,就已经不错了。然而,对于一个已经拥有大量用户群体的框架与 API 而言,则必须追求 OCP 至极致,否则就会因为实现的不稳定性与版本的不兼容性,而被原有客户抱怨,甚至被抛弃。这正是框架设计与通常的企业应用系统设计最大的不同。

托尔斯泰说过:“幸福的家庭总是相似的,而不幸的家庭则各有各的不幸。”设计亦然。好的设计原则可以放之四海而皆准,而设计的缺陷却各有各的表现特征。本书的最大特点是围绕着 NetBeans 的开发来说事儿,诉说其渊源、演化与设计的过失。这是真实的实践,不是拿着可笑的玩具项目阐释设计原则的方式所能比拟的。也许它失之于晦涩艰深,但只要你愿意仔细研磨,收获定能远超阅读的付出。不过,如果你是一位 Java 初学者,那就奉劝你远离此书,它会比“云计算”还要让你云里雾里。或许,你的职业发展目标,应以读懂本书为一个重要的里程碑。当你明白本书讲解的知识时,也许你已经可以驾驭面向对象设计与 API 设计了。

阅读本书最好能结合 NetBeans 的源代码一起分析,如此方能领会设计之妙。其实在我看来,这是本书的硬伤。因为作者在讲解设计问题时,实在太罗嗦了。所谓“一图胜千言”,而对于我们这些代码狂热者而言,代码的清晰度远甚于冗长的描述。书中列出的 UML 图与代码实在太少了,通篇的文字描述让我们在阅读时感觉有些乏味。以我小人之心,会认为本书作者包藏“祸心”,因为本书可以大肆地推广 NetBeans,他好像在说“读不懂吗?不明白吗?那快去下载 NetBeans 啊!”可惜我们必须接受这样的诱惑,因为读懂这本书的内容绝对能够让你的设计能力登上一个大大的台阶。

Rod Johnson 的名著 Expert One-to-One J2EE Development without EJB,在书名中并未提到 Spring,但书中对 Spring 设计的阐释,也许比任何一本 Spring 著作都要通透与权威,因为 Rod Johnson 正是 Spring 之父。本书的英文名 Practical API Design 同样没有提到 NetBeans,但若要论 NetBeans 中的设计原则,本书作者 Jaroslav Tulach 自然是最佳选择,因为他正是 NetBeans 之父。在 JavaLobby 对他的采访(人民邮电出版社编辑李松峰在其博客上翻译了这篇采访)中,Jaroslav Tulach 提到了写作本书的心路历程:“写这本书的素材我已经收集了 10 年之久了,因此我知道这本书绝不可能在短时间内写完。自从去年夏天,我表弟促使我下定决心之后,写这本书大概花了整整一年时间,包括整理笔记和修改润色。”可以说,本书事实上是伴随着 NetBeans 的成长而孕育成熟直至诞生。

本书为我们描绘了 API 设计的壮丽画卷,这里的景色美不胜收,又仿佛如蒙娜丽莎的微笑那般神秘。在设计的旅途中,我们充满敬畏,却又应保持足够的怀疑,这是我一直以来的阅读态度。本书我已经阅读到了第 15 章。书中提到的许多设计技巧与原则,让我欣喜不已;然而也有许多讲解让我疑惑。当我发现,为了保证 API 的向后兼容,不得不牺牲设计上的优雅与美时,这让我有些不快,却又必须无奈地接受现实。还有 5 章的内容,我就要结束本书的阅读了。然而,这仅仅是开始,因为我对书中许多内容依旧抱有困惑,甚至没能明白个中含义。我还需要阅读第二遍,第三遍……经典的书籍就应该这样阅读。

——InfoQ 中文站架构社区编辑 张逸


本书信息

原书名: Practical API Design: Confessions of a Java Framework Architect

原出版社: Apress

作者: (捷)Jaroslav Tulach

译者: 王磊 朱兴

出版社:人民邮电出版社

ISBN:9787115248497

内容简介

与枯燥乏味的理论性图书不同,本书从理论、实战及日常应用三个方面详细讲解了软件开发和框架设计的艺术,着眼于保证软件设计能够应对时刻变化的需求和技术。书中将理论与实践有机地结合在一起,对框架设计领域进行了深层次的阐释。

作为 NetBeans 框架的主架构师,作者在书中总结了自己多年的开发经验,与大家分享了 API 设计的技术细节、走过的弯路与教训。对于广大软件开发人员来说,这些都是不可多得的宝贵财富。

JavaIDE架构Book Review语言 & 开发文化 & 方法