前言
“模型驱动开发”——体会一下这几个词。它们说出了这个不断变化的工业中一个新的改变。这里不是说一种革命,而是一种缓慢的变化,但是肯定会渗透到我们开发系统的方式中。这种推动将降低代码的重要性,并且专注于一些开发中的真正事情:最终的应用程序被期望怎样工作,并确保你能够根据客户的需求可靠地建立起它来。
模型驱动开发是更伟大视景MDA 中的一部分。MDA 是模型驱动体系架构(Model-Driven Architecture)的简称,由对象管理组织OMG(Object Management Group)所驱动。MDA 表示了一种模型驱动开发方法的概念框架。然而,尽管完整的MDA 还没有成为现实,模型驱动开发现在已成为可能。实际上,它已以较低级的形式存在了较长一段时间,所以我们并不是在做某种新的东西(当然,除非你在听某些市场人员的宣传)。
没有魔法
如果模型驱动开发这么好的话,为什么不是每个人立刻加入到这个潮流中来呢?
首先,模型驱动开发不是一个银子弹,能神奇地解决你所有的问题。总有某人需要去实现系统的功能,并且还找不到任何工具来完成这一点。所有你能发现的工具只是使这项工作更容易和直接一些。
第二,采用模型驱动开发,并不只是在开发项目的过程中更换一种工具。它还必须和已根深蒂固的开发过程结合起来(如果没有的话,你就可以开始使用模型驱动开发了;否则你就只能改善当前的情况),但实际上更重要的是,你还会担心它对现有应用程序的影响。决定改用基于模型的方法前确实需要有一些仔细的考虑,并且,一般说来,为了不影响当前的工作,你只会在新项目中改变开发方法。
第三,你还需要获得那些使用工具的人们的支持(你需要一些工具来应用模型驱动开发)。开发人员常会认为“模型驱动开发不是编程”而回避它,并且当心他们的工作难于被接受。他们还可能担心模型驱动开发将会使他们以前辛苦学来的一些技巧过时。他们的担心也不是完全没有理由。采用模型驱动开发后,市场确实很有可能会减少对那些精通好几种编程语言的开发人员的需求。但是另一方面,所有好的开发人员,首先和最主要的是,他们是问题的解决者。他们感兴趣的是尽可能地为手边的主要问题找到新的更好的解决方案。模型驱动开发激动人心的一点就是它允许开发人员集中精力于解决主要的设计问题,增加新的、酷的功能;而不是花费他们的主要时间于改正语法错误,防止内存泄露,或无休止的低级bug 上。
还有第四点,它也是第三点的一个结果,工具必须足够的好。不幸的是,有时用户对工具期待太多,或工具提供厂商承诺过多,实际上却不能交付。这两种情况都很容易使用户放弃模型驱动开发的想法。你确实需要保证工具能够满足你的需求。
可视化软件工程
模型驱动开发的基础是模型和表达模型的语言。模型提供了这样一种能力,能够一致性地显示这个系统的不同视图。一个常见的错误是认为模型驱动开发是模型和代码之间的一种关系,通过代码实现了模型。确实很多情况下,这二者是等同的,但它大大限制了我们的视野。
模型的一个主要用途消除开发过程中各参与方之间的隔阂,需求工程师,系统分析员,软件开发人员和测试者都可以使用同一种语言。你可以注意到,他们可能专注于语言的不同部分,以满足他们的需要,但他们都会共用一些基本的结构,并对他们正工作的系统有一个统一的认识。而且使用统一的语言有助于消除角色间的界限,使得在项目的不同阶段人员转换到被需要的角色更加容易。还有另外一些人需要知道项目的进展情况,包括项目领导、经理和评估委员会。更重要的是,用户也需要知道什么将会被交付,需要加入到整个开发过程中,与创建系统的不同人员进行交流。一种图形建模语言,比如UML,使得各参与方之间的交流成为可能,帮助架起参与方与某些系统复杂功能之间的桥梁。模型驱动开发正逐渐获得公司高级管理者注意,其中的一个主要原因就是这种能够逐渐增加用户、管理层和大的组织机构参与的能力。
那么编程将会怎样呢?它不再需要了吗?我们在这之前提及了一下,现在再详细讨论它。给模型提供足够的信息,工具就能生成大部分和全部系统所需要的代码。请注意,如果你用工具去生成全部的代码,这就相当于编译你的模型。在很多方面,这都类似于当从汇编编程转到C 编程时发生的模式转换,开始的时候,存在一定的怀疑,特别是那些汇编语言编程者。对于模型驱动开发,我们说的也是一种相似的模式转换,建模语言代替了编程语言,用建模语言来实现系统。这主要是因为建模语言正变得更有表现力,允许用户能够指定详细的系统行为。而且,主机上的确认和验证技术能用于检查系统的正确性。在模型中,一般说来你会忽略掉那些令人不快的细节,比如分布式,代理和内存管理,并且让工具去生成它们的代码。这些都表明你还需要对系统的行为进行建模(或者如果你愿意,也可以编程),但你可以在更抽象的层次上进行,关注于系统的重要功能。
你的明星程序员,你记不清他已多少次拯救你的公司了,可能会说,“如果我用编程的方式实现系统可能要快很多。”你知道他说的可能是对的。但是,这是个大系统,或者请慢,他打算对什么编程呢?是谁为他创建了系统规范?难道他不是团队的一部分吗?或者这个系统确实很小,一个人就能够确定规范,开发和测试?即使这样,你愿意所有的信息都只存在这一个人的头脑中?如果他不小心发生车祸,或者你的竞争对手为他提供了一份他无法抗拒的待遇,这时会怎样呢?系统交付以后又会怎样呢?最终用户能够修改实现吗?或即使是理解系统?将来升级,系统维护起来方便吗?
这将我们带入到模型驱动开发的另一个主要用途,把系统和软件开发更多地纳入到系统和软件工程规则中。模型驱动开发是关于开发和维护系统的,系统并不只是由应用程序组成,还包括其他的部分,使得人们可以理解这个应用程序。一个模型可以包含明显可执行的部分,但它几乎总是还有其他部分,并不能被运行,比如需求,系统的粗略框架,商业模型和分析模型。在项目开发时,所有这些都应该被创建出来并保持最新,它们对于将来的维护非常重要。
模型驱动开发的现代工具提供了运行一个(或部分)模型的能力,这使得可以更早得到确认,系统能按预定方式工作。换句话说,这意味着项目风险被极大地降低。在模型驱动开发中,测试也变得更加重要,因为能够被更早和更频繁地进行。这种方式,会使你对在项目后期,应用程序的各部分能够统一合作具有更多地信心。直观地,你可能以为所有这些额外的工作会延长开发周期,但是经验显示,产品上市时间实际上是缩短了。你花费更少的时间用于实现和测试阶段,更多的时间用于分析和设计阶段,当你迭代重复这些过程时,你会发现,这种方式的好处是实实在在的。
UML 2.0 的作用
无疑,统一建模语言(UML,Unifid Modeling Language)就是设计用来进行模型驱动开发的语言。它第一次标准化是在1997 年,作为当时各种面向对象分析方法之争的结果。然后它迅速成为最流行的建模语言,用于“可视化、构造和存档在基于软件的系统创建过程中的产品”。
我们沿着这条道路已经走了五年,用户和工具提供商对于UML 语言都有了更多的经验。我们知道什么很有用处,也知道什么需要被改进。而且,软件工业在这些年也发生了变化,需要去支持一些新的技术,比如基于构件的开发和可执行的模型。这些需求还不能用现在的UML 合适地处理。为了解决这些问题,对UML 大的修订工作两年前由OMG 开始启动,预计于2002 年底前完成。
在语言中新增加的性能,用于对系统架构建模,都是些很重要的部分,使得更容易创建任何复杂度的实际系统。对这种规模可伸缩性的关注也扩展到了其他领域,包括对行为进行建模的图形,比如顺序图和状态机。既然UML 试图适合很多参与方的需要,它需要变成一种相当大的语言,但是并不是每一个人都需要知道语言的所有部分。它被有意识地分割成几种视图或图形,允许你关注于只与你相关的专门领域。其他人可能希望工作在其他的视图上,模型将保持这些视图间的一致性。
工具的考虑
工具实现模型驱动开发的方式各不相同,给予用户或多或少的灵活性。双向工程是一个可怜人的选择,他不能在模型中捕获到系统行为,并且他还把自己与某种特定的编程语言绑定在一起,这还是一种以代码为中心的方法,所有这些都将使你感到难受。在一些紧急的场合,你甚至会忘记模型,比如一个项目就要到达最后期限(看起来在某处总有一个最后期限)了。在项目的最后,你得到了一个可工作的应用程序,还有一个没有实际用处的模型。这时,你甚至怀疑建模的重要性了。
对双向工程问题的一个让步就是在模型中直接插入编程代码,因此强迫你更新模型以确保最终得到一个可执行的应用程序。这同样使你感到难受,又被绑定到某种特定编程语言,你还不得不在模型的很多地方插入代码片断。这很像在C 程序中插入汇编代码,尽管有时这是必要的,但是将来维护会是问题并可能伤害你。
考虑直接在模型中提供指定系统行为的能力,上述两种方法都变得过时。在模型驱动开发中,你只需按一个键,在你选择的平台上,就能获得自动生成的任何语言的代码,这样在模型这一级上就能实现应用程序的可移植性。你不需要修改代码,改变你的系统就能直接反应到模型的实现上。当然,目前还有一些路需要走,大部分的工具厂商目前都有他们自己的语言映射,但要实现MDA 的目标,就需要有对不同语言和平台的标准映射和脚本。好消息就是这种前景正在展现。模型驱动开发确实正在起作用,并必将改变我们开发系统的方式。