1.大公司手中的算盘
从最早仅仅关注于软件开发工具到现在,软件行业中的巨头们已经在层出不穷的思想中涅槃了一回又一回。
Rational被IBM并购的真实原因在于IBM需要构建一个完整的软件工程体系,有了Rational的IBM会变成这个样子(见表1)。
对于Borland来说,对软件开发语言(C、Java、Delphi)把握是其自身优势,所以Borland一直保持在语言上的中立,以寻求一种在不同平台上的开发者社群的支持最大化。Borland积极的推动UML的标准化,一方面可以使得Borland有机会在模型语言标准的制定上有机会制造影响,另一方面也可以快速地与IBM/Rational构成对抗Mircosoft的战线。
作为工具开发商,Borland快速地拥有了实现ALM(Application Lifecycle Management)所需的绝大多数软件产品。然而Borland也很快意识到,(当前的)ALM是一个产品体系而不是一个理论体系:Borland没有在ALM作为工程理论方面上的任何优势。于是Borland开始并购与实现ALM体系相关的公司,其中收购过程改进咨询公司TeraQuest并组建流程优化实务部,以及收购TogetherSoft为开发工具增强模型构建能力,都是相当大的一些举措。通过这些努力,Borland快速地补全了ALM作为一个工程体系在理论方面的不足。
对于IBM来说,RUP和UML是优势,所以IBM用来削弱Borland在开发语言上的优势的最佳手段,就是支持开源的Eclipse,以及用UML的标准化来确立其规范制定者的地位。然而你会惊异的发现,Borland一方面在支持UML的标准化,另一方面还在支持着Eclipse的开发并协助其快速成为一个完整的、具有商业品质的开发平台。这似乎是极其怪异的战略:帮对手磨剑。
如果Borland只为一个对手磨剑,那他可能是一个傻子。但问题是,Borland几乎为他所有既已成为(或者终将成为)对手的人磨剑:Kylix是Linux平台上的产品;C++
Builder、C# Builder、CBX、Delphi是Win 32和.NET平台上的产品;JBuilder则是Sun平台上的产品——
一切正如Borland自己说的那样,他是“(语言、平台和技术)中立的软件厂商”。
Borland走在钢丝绳的中间,对他的考验是平衡的艺术和技术:如果他倒下,钢丝绳两端的任一方都来不及施以援手;然而如果他存在,那么他向哪边迈出的一步,就给对方以最大的压力。
“敌人的敌人就是自己的朋友”,聪明的战略家总是能看到这一点。然而Borland却力图使这个敌我都分不清的战场呈现出一种古怪的格局:一方面Microsoft是Borland的股东之一,另一方面Borland在做Sun、IBM以及Linux平台上的软件提供商。
与Borland和IBM通过通过并购来达到目的方式,Microsoft有足够的力量全方位出击,因此你看到的体系如表3所示。
Microsoft在工具、方法和过程方面都有具体的实现。而IBM在方法和过程层面上大都停留在理论阶段,Borland在这些方面上虽有丰富的产品实现,却又相对缺乏理论基础。
Microsoft并不仅停留于此。从.NET Framework提出开始,Microsoft就试图在开发语言和基础框架上实现大统一,希望能达到UML在模型语言中的地位。因此出现了CLR+CTS通用语言体系以及其具体的实现:.NET
CLR+IAsm。.NET上的代码要求最终被实现成中间代码,可以反汇编到IAsm,这意味着任何其它公司在开发语言层面上的优势丧失殆尽,所以开发者们看到C#、Jscript
.NET和VB .NET同期实现的“壮举”。
而Mono的出现,对于Microsoft而言是绝对的福音。Microsoft把.NET Framework中的C#、公共语言架构(CLI)以及通用类型系统(CTS)等做成ECMA标准,最期望看到的就是类似Mono这样的第三方产品的出现。事实上,Mono做了Microsoft从来都想做而不敢做的事——解决了Microsoft产品的跨平台问题,进而削弱了Sun相关语言的跨平台优势。Microsoft一方面不想放弃自己的平台优势,另一方面又为Sun的跨平台优势所制肘。而Mono的出现以及它适度的影响力,正好成为Microsoft平衡这种微妙的、相对优劣形势的棋子。
接下来Microsoft开始向模型语言发难。领域专用语言(Domain-Specific Language,DSL)的提出绝非偶然,那是在硝烟未尽的战场上重新燃起的战火。
软件业界如今的局面,不是一些人(例如程序员或者评论家们)争争吵吵的结果,而是大公司们相互制衡的结果。Borland与IBM、IBM与Sun以及Sun与Apple都在做着相同的事,
又都有各自的算盘。他们一边压制对手的优势,一边又借助对手和同盟的力量来削弱自己的劣势或者补充实力。
跳到局外来看,并不是说Microsoft是他们的共同对手,而只是因为Microsoft占在了峰头浪尖,便成了众矢之的。所有人面对的并不是Microsoft的名字,而只是它的地位,无论谁成就了这个地位,都将承受相同的风险与压力——当然也包括机会。
众多大公司在标准、理论、语言上的争来夺去,未必全部出于“软件实现”的考虑。对统一理论、统一工具、统一过程的企图,其最终目的是在整个软件工程体系中的全面胜出。算盘上的绝大多数人,只是用于计算胜负的一枚算子。
2.回到工程的关键点
除了软件本质力量的推动之外,商业因素也推动着软件工程体系的发展。大公司之间的争夺战的最终结果,已经开始把软件工程从原始的“自生演进”状态,逐渐推进到“他激发展”的状态上了。
这种他激发展可能会影响到软件工程发展的速度,然而在各个工程层面上的关注点并不会发生变化。在前面的模型图中,每一条纵向的细线用于定义一个关注点①。我在另一次培训中为这些关注点加上了标注:
上图标示的模型被我命名为软件工程层状模型(EHM, Engineering Hiberarchy Model)。与“牛屎图”所代表的“软件工程体系层次”不一样的是,EHM不描述工程元素间的关系,甚至在试图割裂这些元素以使得工程角色定位以及各自的视角更加清晰明确。
从这个模型中可以看到,在“程序”与“方法”层面,是关注于“(具体的)实现”的;而在“过程”和“工程”层面,首要考虑的是团队问题。从角色的角度上来说:开发经理思考项目的实施方案和管理具体的开发行为;而项目经理则保障团队的稳定性和一致性。
然而这只是基本模式,或者说,是理想模式。
3.思考项目成本的经理
在标注关注点时,如下的问题引起了我的思考:
项目的管理到底是组织管理还是成本管理?
项目的计划到底是组织规划还是成本计划?
一言以蔽之:项目管理要不要考虑成本问题?
现在,从一个细节跳出来,进而分析我们的角色。这个细节就是:如何完成今天的工作。
正如前面所说,如果你是一个软件公司里的项目经理,你今天的工作可能是写一份项目计划案或者听测试部的报告,亦或安排会议来听取和分析一个新的产品需求。然而,我需要说的是:这是细节。
细节就是你使用的Project 2003,或者你正在公司内部署和推广的ClearCase。如果它们正好是你今天要完成的工作或者是你明天要用来工作的工具,那么,做为项目经理的你,现在就要立即跳出来。
理想状况下,“软件工程=过程+方法+工具”。然而,工程成功的真正关键并不在于你把你的团队“组织”得有多好。即使在团队中他们都显示出有条不紊,你一样会面临失败。
蚂蚁的团队总是被本能地组织得非常好。然而如果一个蚂蚁的群体中有了流行疾病,致使蚂蚁死去,而新生蚂蚁不能跟上其死亡的速度,那么这个团队很快就溃散了。
这是因为蚂蚁用于维护团队运作的“资本”在流失。如果资本没有了,就没了运作,团队的存在就没有了必要性和可能性。项目就死亡了。
埋头于画甘特图的项目经理犯下了与挖山不止的愚公同样的错误:忽略了成本。
如果愚公真的可以成功,那么可能是300年之后。然而如果一个工程要300年才能做成,那么在做成之前,客户就选择了放弃。
如果有机会,项目经理可以选择向另一家公司购买一个产品来卖给客户,从“为客户开发”变成“为客户定制”以及“为客户服务”,这样就在没有任何开发成本的前提下完成了工程。与另一个同样极端的例子相比,你会发现它与前面那个“做过场”的项目全然不同。后者是做完了工程,却没有做成工程。而现在这个项目经理却做成了工程,但是在许多的过程环节上他根本就没有开始。
然而,现在除了跃跃欲试的技术经理之外,没有人会不满意这个结果。
技术经理最常说的话是:我们可以开发出来;开发人员最常说的话是:我可以开发出来;愚公最常说的话是:何苦而不平?
还记得那句话吗——不要栽进蚂蚁洞里!
愚公如果停下来,思考的问题可能是碎石的“方法”。而项目经理从细节中跳出来,思考的问题就应当是完成工程的“方法”。评价这个 方法的好坏的标准只有一个:节约成本。
Y公司由K公司过渡而来的时候带来了一个市场前景非常看好的产品。而存在的问题则是两方面的,一是扩大市场占有率,二是继续技术投入。
于是,Y公司请来了专家D。他是一个在行业中摸爬滚打了多年的顾问型专家:做过公司,也在无数个公司做过。D先生的项目计划可能是无可挑剔的,但其投资规模决定了它无法实施;D先生在一些产品计划上的思考上也是切近市场的,然而他没有学会如何为团队争取到两名以上的开发人员;D先生在部门管理上的方法也是适当的,然而他忘记了训练部门人员以使他们与自己保持一致的步调和方向(组织和管理一个松散的团队比照顾一群蚂蚁难得多)。
于是在Y公司建立到倒掉的四年时间里,D先生三进三出,营销计划一再被否决,而产品的再研发计划也数度被搁置。很快,这个并不生动的故事终结于我跟他的最后一次会谈:三年之后,产品彻底从市场中退出。
“思考成本”,这是D先生给我的教训:
不计成本的项目计划不会得到经营者的支持;
毫无目的地消耗成本是项目中的慢性毒药;
最致命的风险是成本的枯竭②。
===================================================================================================================
===================================================================================================================
4.审视AOP
我读到的第一篇关于AOP的文章居然说它是“新一代的java语言”。正如文章的标题所表现的那样,作者大概是在学习如何向方格子里填写“错误”:其结果当然是每一个格子都是“错误”——如果他象小学生一样勤奋的话。
AOP不是语言。AOP首先是方法论,这就像OOP是“面向对象的编程方法”的方法论一样。而Delphi/C++才是语言,是对这个方法论的一个实现工具。
很好,有了这个基础,我们再来讨论相似性的问题。我们提到过开发方法是基于一种数据结构的编程实践的结果。很显然,OOP所基于的数据结构是对象(Object),而AOP所基于的数据结构就是方面(Aspect)
③。落足到开发工具的实现上,Delphi将Object表现为一组有(继承)关系的“记录(Record)④” 。相对应的,Java将用类(Class)来实现Aspect。
===================================================================================================================
③人们在争论Aspect到底应该译成“切面”还是“方面”这件事上花了很多功夫。其实,就如同讨论前面的“关注点”究竟是“点”还是“线”的问题一样,他们陷入了细节。如果这些细节被作为问题持续下去,那么可能有一天台海战争将不是发生在军队之间,而是在程序员之间:到底是“物件”,还是“对象”?
④在C中,这个名词是“结构(Struct)”。很多人不会承认“对象是有继承关系的记录”这样的观点。是的,所有的教科书上都不会这样写。但是从数据结构本身以及数据结构在语言中的实现来看,对象终究是记录。记录是平板化的内存存储体系中所能表达的最复杂的单一数据体。
===================================================================================================
Aspect在定义时没有确定的对象模块,Aspect本身只是对一个“对象模块群体”的观察视角,因此它更易于表现成接口——只有描述而没有实现。
在Object一层的抽象上,Object关注于“有继承关系的考察对象”的个体特征;而在Aspect一层的抽象上,Aspect关注于“有相似需求的考察对象”的群体特性。其相似性在群体中表现得越广泛,则AOP的优势也就越明显。例如在Delphi的VCL框架中,以下两个需求就可以用AOP的思想来实现:
使Delphi中的全部对象具有多线程特性(即线程安全);
实现助手工具类以观察、控制Delphi对象的运行期特性或表现。
到现在为止,我们弄清楚了AOP作为“思想、方法、工具”的一些基本知识,以及它的应用范围:至少你要明白,它是用来考察对象(而不是设计对象)的思想方法。
所以接下来AOP的三个概念我们就明白了:
指示(Advice)/拦截器(Interceptor):考察这些对象以“达到什么样的目的”(即需求)。
引导(Introduction):在目标上实现这些需求时,目标所需要表现出来的公共特性。引导特性可能需要配合编译器来实现。
元数据(Metadata):如果需要,为即有对象实体再补充一些参考数据。
确切地说,切分点(Pointcut)并不是AOP编程方法所需要的概念,而是AOP作为一个框架时所需要的一个工具:一组辨识Acpects和Objects的索引。
现在你已经会用Acpect的思想来编程了,而无论它是用Java来实现的,或者是用C#、Delphi,乃至于FORTRAN或COBOL。你需要做的是,回到工程最核心的那个环节:编程=算法+结构+方法。
5.审视MDA/MDD
MDA(Model Driven Architecture)也是一个方法论层面上的名词。它讨论的是“创建出机器可读和高度抽象的模型”的方法。受MDA影响的开发活动被称为MDD(Model
Driven Development)。
与MDD在同一个层面上的概念是:
TDD(Test Driven Development)
FDD(Feature Driven Development)
BDD(Business Driven Development)
R-TDD(Rapid Template-Driven Development)
CDD(Contract Driven Development)
RDD(Requirements Driven Development)
... ...
我不厌其烦地罗列这些名词,只想告诉读者一个事实:什么都可以“驱动开发”。
不同的方案提供商基于自己的产品构架和当前的理论倾向,随时都在准备改变他们“驱动开发”的方式。在这种形势下的 “xDD”或“xDA”,已经成为他们促销产品的保留用词。
回到软件工程的过程环节中来吧,你会看到,“以什么驱动开发”只是一个“以哪个环节为中心(或导引)”的问题。所以你会看到TDD中的X模型(也可参考V模型)是这样的:
如果你仍旧不能明白为什么会有这么多被神秘力量所“驱动着的开发”,那么你就干脆去厨房找个平底锅烧点热油,然后敲下一个鸡蛋,很快,你就体悟“以蛋黄驱动开发”的真谛了。
抛开实现的技术细节不论,在工程中,“以什么驱动开发”其实是一个过程问题。而你应该明白,过程的选择(或制定)取决于你的工程需要,以及它在相关应用领域的适用性、过程工具的充备性和这个过程理论的完善程度,而不是大公司们的鼓吹。
过程模型决定了工程的实施步骤和组织方式。但是Object Management Group (OMG) 尽管对MDA提出了一套完备的技术和方法体系,工程实施者却无法在这个体系中找到一个可以适用的软件过程模型——MDA不讨论过程。
也就是说,MDA架构作为一个新的软件开发方法的架构,即使在技术研究、底层协议和软件实现方面经过了持续地完善而渐至成熟,然而如果没有同样成熟的软件过程理论支持,那么它在工程中的实用价值也就有限。
仔细审视一下这个MDA,如果你现在就决定将下一个工程项目建立在这个构架的基础上,或者用MDD的方式来开发BIOS,那么你离精神病就不远了。
①我画出的的确是线而不是点,“关注点”只是一个概念。如果你非要去发现一个“点”,那么你可以用几何的目光,关注于弧线与直线的切点。然而,这样的结果将是你彻底的忽视了“关注点”的本质含义。
②我经常注意到的成本因素包括时间、人力、资金和客户成本。而大多数情况下,人们不会把客户的数量以及耐心当做(客户)成本来计算。而在我的项目规划中,这是成本。 |