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

时间:2017-12-06 13:00

不知有多少人和我一样,对自己日常使用的开发框架和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中文站架构社区编辑 张逸