软件过程的改进是一个长期的过程,属于长期的利益。如果长期利益和短期利益相冲突的时候我们应该如何处理。我们有什么办法来令短期利益和长期利益结合起来呢?
意图
权衡短期利益和长期利益。
示例
金商软件是一家专门针对小型企业销售软件产品和定制开发的公司。他们销售的软件来自于国内的一家知名软件厂商。而公司内部的软件人员主要从事定制开发,一方面是满足用户的一些特殊需要,另一方面是为了发展自己的软件开发力量,以图日后开发出自己的产品。这种策略刚实施了半年的时间,目前公司的开发人员只有5个人。由于公司的销售能力很强,因此公司总是能够得到大量的订单。由于公司目前已经拥有开发力量,因此得到的订单也不像从前,以产品为主,定制为辅。而是一些完整的开发项目。从10月份开始,公司已经签了4个项目,按照公司的习惯,一般都承诺在3个月内完成项目。可是根据软件部分的估算,目前的任务,大概需要60个人月的时间。到了11月,开发部的所有人员已经连续加班1个月了。其中2个项目由于增加需求,同意把项目的开发周期延长一个月,但是和60个人月的工作量比起来,这点时间似乎是杯水车薪。在时间的强大压力之下,开发人员不得不牺牲软件质量,而软件的最后完工看起来是那么的遥不可及。
上下文
自从加入到面向对象开发地阵营以来,我们深为这门开发艺术所感动。编码工作在面向对象思想地指导下显得那么具有美感。以往过程式编码失控之后的那种无力感再也找不到了。面向对象带给我们的是极大限度的重用性,当然,我们需要付出前期投入的成本。从学习面向对象以来,我们学会了使用一种抽象的方式看待世界,思考问题。有些时候,我们同一些仍然保持传统编程习惯的软件公司交流时,我们发现似乎面向对象并没有体现出太大的优势:
"面向对象技术可以极大的重用现有的构架,大大提高开发速度。"
"我们现在通过增加人手和加班的方式,也能够很快的完成一个项目。"
"面向对象技术可以减少软件的维护成本。"
"一般我们会指定一些开发新手来维护公司以往的项目,这方面的成本并不高。"
"面向对象能够不断的积累项目经验,为后续的项目开发提供保证。"
"通过雇佣有经验的开发人员,我们可以直接获得开发经验,而不用自己积累"
"面向对象是未来软件开发的主流。"
"保证项目及时完成是管理层最关心的,等到市场上的面向对象程序员足够多之后我们再采用面向对象吧。"
"此外,现在采用面向对象,人员需要全新的培训,我们没有多余的人手;由于没有经验,直接把面向对象用于项目实施存在风险,而我们的项目时间都太少了"
这一段对话点出了面向对象技术的困惑,但也反映了软件开发中短期利益和长期利益的冲突。
问题
如何在软件开发的短期利益和长期利益中寻求平衡点?
方法
面向对象的迷思
我们的疑惑是从面向对象开始的 。归结其原因,是我们并没有真正的认识面向对象。
"面向对象符合现实世界的特性,因此会更加简单。"
"我们决定从这个项目开始采用面向对象技术,并安排了为期2周的学习时间。"
"由于采用了先进的面向对象技术,我们把开发周期缩短1/3。"
如果你对面向对象有上述的理解的话,说明你对面向对象技术的理解存在误区。首先,面向对象和面向过程的不同在于思维方式的根本不同,因此,转向面向对象技术决不是一个一蹴而就的过程,而是需要不断的学习,不断的磨练。如果需要为这个学习过程制定一个时间的话,我想也应该是在8~14个月之间。其次,在刚开始采用面向对象技术时,并不能够节省项目的开发时间,相反,因为学习和尝试面向对象技术的需要,项目的所需时间会大幅度延长。面向对象技术的威力在经过一段时间的积累之后会慢慢的显露出来,你会发现一个新的软件只需要对现有的类进行重用,编写少量的代码,甚至使用代码生成器就能够完成。这使得软件的开发成本大幅度的降低。这个时候,软件开发将会进入良性循环的周期。
为什么面向对象技术会有如此大的威力呢?原因在于面向对象的抽象思维。
了解了面向对象的知识之后,我们发现其实面向对象的主要威力是它使用一种特定的方法,将一些不断重复的事情简化了。问题在于,要让软件组织学会使用这种方式是需要代价的。那么,你是否愿意付出这种代价?今天付出1块钱,明天能够收回10块钱的事情每个人都会做。但是让你每天投入10000块钱,坚持2年,这样你会在未来获得10倍的回报。这种事情就未必会有人做了。研究面向对象技术,发展软件组织的技术框架需要很大的前期投入,而效益却是慢慢显现的。这就造成了短期利益和长期利益的矛盾。其实,除了面向对象技术之外,软件组织中还存在很多同种性质的矛盾:
所有人都知道项目管理的必要性,甚至言必谈项目管理,但是真正按照项目关联方式执行的又有多少人呢?
软件质量是软件组织最看重的,但是由于人员和时间的压力而牺牲质量的案例多如牛毛。
计划制定和执行是软件过程中最核心的部分,可是计划赶不上变化也是目前最流行的口头禅。
由于我们主要讨论的仍是经验,关于项目管理的原理、案例、数据的资料有很多书籍都有介绍,因此我们就不用再次的重复它们了。而我们的出发点,仍然是围绕着前述的核心矛盾,介绍一些实践。这些实践并不需要很大的成本,但是确实能够起到很好的效果,当然,它们最能够发挥作用的前提条件是――"坚持"。从下面的介绍来看,其目的都是为了补充或完善框架的问题。在之前的模式中,我们多次提到这个词。这里我将给出其定义:
框架是软件组织对技术、实践、方法、过程、经验的有序积累。
用时髦的话来说,就是知识管理。框架不是一开始就存在的。它需要积累,它的内容很广泛,不仅仅包括技术,还包括项目经验、软件过程、管理思想、组织设计等等内容。和开发软件相关的内容,它都包括。框架能够避免软件组织不断的发明轮子,能够将原先存在于人员脑中的隐性知识转换为显性知识。但是如果你没有一个清晰的建立框架的思想,没有一个明确的框架发展目标。框架是不会自动出现的。
坚持面向对象技术的学习和使用。我们已经花了一部分的篇幅讨论面向对象的优点。那么我们如何评估它呢?首先,如果软件组织没有面向对象的经验,最好的方式是求助外界,无论是培训,还是聘请面向对象开发人员都是有用的。光凭自身的积累是比较慢的。其次,慎重的使用面向对象技术。作为一种新的技术,总是存在较大的风险。因此,尝试的在一些较小规模的项目中使用它,切忌急功近利。对于完成的面向对象的设计,应该将其纳入到框架中。
纳入到框架中的设计和代码需要严格对待。因为它将会成为权威性的资料。设计需要经过复审,代码需要通过测试。此外,还需要配套必要的文档。必须要讲清楚为什么要这样设计,设计的思路,达到的目的,可能适用的环境。这些都会对读者产生帮助。现实中,我们发现模式语言是一种很好的编写文档的格式。因为它的名称、意图、上下文、问题等部分给出了解决方案的前导叙述,能够让读者迅速浏览,并判断该模式的价值。而解决方案、相关模式、已知应用等部分在描述了解决方案的同时还扩展了读者的思路。而模式语言的可扩展性也意味着你可以根据自己的需要加入不同的元素。
在框架中建立项目经验库是很好的做法。但并不是所有的软件组织都能够做到这一点的。因此我们采用一种折衷的方法。对上一次项目经验进行复审。在每一次的项目开始之前,我们都需要问问自己,上一次项目有什么成功和失败的地方,这次的项目如何利用成功经验,吸取失败的教训。可以采用会议的形式。这会起到很好的效果,但不要让这种会议流于形式。
长期利益和短期利益的结合
软件工程并不意味着轰轰烈烈的公司运动,至少我是这么认为的。也许我属于温和派,比较倾向于逐步的改进软件过程。很多时候,优良的软件过程往往来源于平时的日积月累,一点点微小的改进。说明这一点最有效的证据就是软件度量。我们知道,软件度量是一个很重要的概念,在实际工作中也非常的实用,例如,我们可以统计出软件组织中单个人月的价格,可以统计出完成某个人完成某个模块的时间长度。可是软件度量需要一个长期的数据收集的过程,但这个工作一旦完成,就能够作为进度控制的基础。软件度量并不是本文讨论的重点,但是应该认识到,软件度量的工作,就属于典型的长期利益的工作,而平时的工作量其实不大,关键在于要有这方面的投入。
从某个方面上说,软件度量也可以纳入到可重用框架中。在可重用框架的范畴中,像这种长期利益和短期利益并不矛盾的例子还可以找出很多。例如单元测试。现在的软件组织已经日益的强调测试了。但是测试工作往往存在着很多误区,直接导致的后果就是成本上去了,但是并没有获得预期的高质量。由于人员的增多,流程的复杂化,还会产生不少诸如沟通之类的额外的问题。为什么呢?其实测试产生的很多问题是因为软件过程的上游没有做好的缘故。例如需求的缺陷或是设计的缺陷。越是上游的软件活动,在出问题的时候,对测试工作的杀伤力越大,这一点和变更是相同的。因此,测试人员的主要工作应该是要解决这类的问题,让测试人员参与到需求分析或是设计工作上来,能够有效的改进软件的质量。但是目前测试人员大部分的时间往往是在处理一些代码级别的缺陷。这实际上是比较浪费测试人员的宝贵精力的。因此,XP中倡导的单元测试能够让编码人员自行处理代码级别错误,从而让测试人员把精力放在更重要的部分上。像这样的实践,见效快,并不需要很大的投资。唯一需要投入的就是对目前的软件流程进行分析和改进。
长期利益和短期利益的另一个例子是一致性。在软件组织发展的初期,一致性问题往往并不明显。更重要的目标是完成软件的功能,至于实现的过程并不被关心的。但是随着软件组织的发展,积累的增多,渐渐就会出现重复的代码、不规范的设计、混乱的软件。当这些问题发展到非常严重的地步,已经严重影响到软件组织的发展的时候,你会惊讶的发现,解决这些问题的代价是极为高昂的。其实,这些问题如果能够早些加以重视,原本是不会发展成为一个可怕的泥潭的。例如,针对出现软件设计混乱的情况,就应该制定标准、规范的设计框架;针对代码重读、不标准的问题,就应该通过代码模版、复审等活动来加以规范。软件工程的真正意义往往就体现在这些看似不起眼的活动上。不注重短期的投入,往往会损害长期的利益。其实,上述的问题还可以做的更好一些。在MDA的概念中,提到了模式和企业应用的关系。MDA认为,利用模式来作为描述业务对象的基础,并把模式根据抽象程序进行分层,可以极大程序的实现重用,并可以保持业务对象模型中的一致性。
软件组织对软件过程的改进很难做到彻底的,革命性的。更多的时候,我们是在"补短板",就像是木桶理论所说的,发现哪一块的木板最短,就改进哪一块。但是要正确的识别出最短的木板也不是一件容易的事情。因为软件过程中的各个活动具有高度的关联性。确实需要花时间来对过程进行分析。
小结
处理好短期利益和长期利益的关系。
根据软件过程的特点决定选取实用的实践。
我们从面向对象技术开始我们的讨论。其目的有二:一是介绍面向对象的经验;二是引出我们的主题――如何缓解短期利益和长期利益的矛盾。(注意我们使用缓解一词,而不是解决。)