Java应用架构设计:模块化模式与OSGi
上QQ阅读APP看书,第一时间看更新

3.2 关于软件架构的一个故事

软件架构使我想到了下面的这个故事(霍金,1998):

一位著名的科学家(据说是贝特郎·罗素)曾经作过一次关于天文学方面的讲演。他描述了地球如何绕着太阳运动,以及太阳又是如何绕着我们称为星系的巨大的恒星群的中心转动。演讲结束之时,一位坐在房间后排的矮个老妇人站起来说:“你说的这些都是废话。这个世界实际上是驮在大乌龟背上的一块平板。”这位科学家很有教养地微笑着答道:“那么这只乌龟站在什么上面呢?”“你很聪明,年轻人,的确很聪明,”老妇人说,“不过,这是一只驮着一只一直驮下去的乌龟群啊!”

——《时间简史》史蒂芬·霍金

软件架构就是“一只驮着一只一直驮下去的乌龟群”。 [1]这是怎样做到的呢?这一节将会讨论这些想法。

3.2.1 象牙塔

我们中的很多人可能都接触过象牙塔。在一些功能失调的组织中,架构师和开发人员不能有效地交流。结果就是双方都缺少透明度和理解。如图3.1所示,架构师将他们的智慧转送给开发人员,而开发人员不能将高层次的理念转化为具体的实现。经常会出现故障,这是因为(尽管我知道还有其他的原因)架构师关注广度而开发人员关注深度。每个组对软件架构都有不同的见解,尽管两者都信誓旦旦,但是在他们所理解的中间区域存在一个空白。架构师可能关注应用和服务,而开发人员可能更关注代码。遗憾的是,在他们的关注点之间还有很多事情。广度和深度之间的空白区域形成了象牙塔架构。

图3.1 象牙塔(the Open Group)

3.2.2 乌龟和塔

毫无疑问,象牙塔架构的功能是有问题的,它的表现就是缺乏架构上的完整性。假设为了帮助架构师和开发人员,要怎样弥补广度和深度之间的空白呢?如何才能更有效地交流呢?怎样才能增加相互理解和透明度呢?

让我们通过另一种定义形式重新看一下软件架构的定义。我最欣赏的软件架构定义是Ralph Johnson提出的,Martin Fowler在一篇文章中(2003)对此进行了引用。他说:

在大多数成功的软件项目中,从事该项目的专家开发人员对系统的设计存在共识。这种共识称为“架构”。共识包括如何将系统分为组件以及组件如何通过接口进行交互。这些组件通常会由更小的组件组成,但是架构只包括组件以及能够被所有开发人员所理解的接口……架构是重要的事情,无论它是什么。

这个定义与本章前面的那些定义的关键区别在于“共识”,它表示软件架构中有社会性的方面。对于系统如何拆分为组件以及它们之间怎样交互,我们必须建立共识。架构不仅是一些技术理念,它也是一个社会性的结构。通过架构的社会性方面,我们可以弥合架构师和开发人员之间的分歧。

为了保证共识,必须要实现自上而下的架构(architecture all the way down,参见6.1节)。架构师不能仅关注服务,开发人员也不能仅关注代码。每个组必须都要关注巨大的中间地带,如图3.2所示。

图3.2 自上而下的架构

仅关注高层抽象是不够的。只强调代码质量也是不够的。我们必须通过其他方式消除这个断层,这包括模块和包设计。通常,在各种会议上演讲时,我会要求那些从事服务设计的听众举手,很多手举了起来。我还会要求那些从事类设计和代码质量的人举手,同样,有很多手举了起来。但是,当我要求那些从事包和模块设计的人举手时,只有很少比例的人举手了。

这是很令人遗憾的,模块和包的设计在重要性方面是与服务和类的设计相同的。但是在这个过程中,我们强调了服务和代码质量,而忽略了它们之间还有什么。在每个应用和服务内部都会出现腐化的设计,即便是在最灵活的代码上构建的应用和服务,也有可能充斥着重复难以理解的代码。富有弹性的包结构以及对应的软件模块将会帮助你消除服务和代码之间的断层。模块化是很重要的中间技术,它能够帮助我们实现自上而下的架构,这种架构会填充广度和深度之间的鸿沟。

我们需要关注模块化,以保证所讲述的架构故事始终是一致的。它是将一切绑定在一起的黏合剂。它有助于连接低层次的类设计与高层次的服务设计。它能帮助降低象牙塔、增强通信、增加透明性、确保互相理解并检查多个层级的一致性。它使得我们能够实现自上而下的架构并实现架构的目标。

[1] 关于“海龟背地球”的故事,此处对应的原文是“turtles all the way down”。如果想更多地了解这个俗语的来历,读者可以参考维基百科的如下地址:http://en.wikipedia.org/wiki/Turtles_all_the_way_down。在本书中,作者使用了类似的词汇“architecture all the way down”,指的是架构不仅要关注高层的服务,还要关注中间的模块和包甚至是底层的代码,本书将这个短语译为“自上而下的架构”。——译者注