我在曾经从事的很多软件开发项目中观察到,软件开发中一直存在这样一种现象:您实际拥有的架构往往与想象中的不同。

通过分析代码的度量报告,比如由 JDepend (参阅 Resources)工具生成的报告, 您可以有效地判定代码是否实现了确定的架构。有些团队对代码做反向设计,得到对应的 UML 图表,也能够达到上述效果, 还有一些团队甚至在编程时使用 IDE 生成相同的工件 —— 即实时反向设计。可是, 所有的这些方法都还是 反应式(reactive)的。 您必须手工审视并分析报告或图表,确定架构是否存在偏离,而有时这种 偏离可能很久之后才被发现。

设想每当某部分代码与 期望的架构有所违背时,您得到一个提示 —— 比如一个 Ant 构建脚本失败 —— 如清单 1 所示:

清单 1. 违背架构导致构建失败

 ...
 BUILD FAILED
 ...
 build.xml:35 Test ArchitecturalRulesTest failed

 Total time: 20 seconds


关于本系列
作为开发人员,我们的工作是为终端用户实现过程自动化; 然而,很多开发人员却忽略了将自己的开发过程自动化的机会。 为此,我编写了 让开发自动化 这个系列的文章,专门探讨软件开发过程自动化的实际应用,并教您 何时以及 如何成功地应用自动化。

本文所提及的技术能够使您通过实现构建自动化主动分析软件架构。 除此之外,本文的示例还演示了如何基于规则触发构建过程失败,您可以使用 JDepend 的 API 和 JUnit 定义这些规则。

当然,重要的是,通过构建自动化,您和您的团队能够在开发周期的 前期发现 源代码与确定架构之间的偏离。 这是我所说的掌控架构!

反应式地设置开发阶段

图 1 说明了在构建 Web 应用时一种常见的架构模式。 presentation层(代表一组相关的包)依赖于 controller层,controller层依赖于 domain和 business层,后,business层依赖于 data和 domain层。

图 1. 典型 web 应用的一个架构分层图

至此,一切都很好,是吗?但是,我很确定您以前遇到类似的情形,那些常见的佳实践规则会在日常的软件开发中被遗忘。事实上,这一点很容易(也很快)会发生。

举例而言,图 2 阐明了对该示例架构的一个微小违背;在这个例子里, data层至少调用一次 business层:

图 2. Data 层正在调用 Business 层的一个对象,由此产生了架构违背

架构的微小变化产生的意外影响使代码的修改变得更加困难。实际上,现在对一个代码区域的修改 会要求其他很多区域的变动。举例而言, 如果您清除或改变 business 层中类的一些方法, 则可能需要从 data 层中清除某些引用。当更多的违背发生时, 修改代码会更加困难。

若使用传统的监控技术,比如查看 JDepend 或 Macker 报告(参阅 参考资料), 您能够多快地发现对期望设计的偏离呢? 如果您和我一样,想快速地生产出能够工作的软件, 那么越快发现影响交付速度的问题越好, 难道您不这么认为吗?