傅纯一

国贸饭店的流程改进

fucunyi | 17 七月, 2007 10:47

上周出差到北京,入住国贸饭店。早上去三江咖啡厅用自助早餐时,注意到每张桌子上都放了一块小小的牌子,一面是绿色的“正在用餐”,另一面是红色的“用餐完毕”。我是国贸饭店的老住客了,这是他们发明的新玩意儿。以前就发生过出去取水果,回来发现座位上的餐具都已经被清理了;或者是早上自助用餐高峰时节,服务员不太确定空位上的客人是否已经结束用餐。我很赞赏他们的这个小小改进,用完了早餐以后很自觉地把绿色的牌子翻到了红色“用餐完毕”那一面,表示我坐的位子可以清理给下一位客人了。不敢保证所有的客人都会遵守这个规则,但总归是一种改进。

这是一个典型的流程改进的例子,业务流程的改进不一定都是请咨询顾问来做的BPR(Business Process Re-engineering),只要大家开动脑筋,任何有助于把工作做得更好的改进都是值得提倡的。曾经看到一个故事说一家日本公司的员工发现传真用纸上都印了格子线,这些格子图像信息也会在传真时一起传输,所以他提了一个建议用白纸来写传真文件,结果大大提高了传真的速度,也帮公司节省了很多的电话费。所以大家在日常工作中有什么好的建议都提出来吧,无论大小,只要是有助于优化改进业务流程的。


关于SOA/CBD/AOP/OO的体会

fucunyi | 06 七月, 2007 10:53

出差途中看了几篇AOP的文章,总算对AOP有了一个初步的了解,是一个非常不错的技术,传统编程技术无法解决的横切(CrossCutting)问题在AOP中可以得到很好的解决。简单比较一下现有的几种技术SOA/CBD/AOP/OO。
SOA - Service Oriented Architecture (面向服务的架构)
CBD - Component Based Development (基于构件的开发)
AOP - Aspect Oriented Porgramming (面向方面的编程)
OO - Object Oriented (Analysis / Design / Programming) (面向对象的分析/设计/编程)

这几种技术本质上体现的都是我们过去几十年软件开发的最佳实践经验。

1) 模块化 - 把复杂的系统(或问题)分而治之,内聚程度比较高的内容组合在一起形成模块,整个系统就是由一系列大大小小的模块所组成。跟复杂的系统相比,单个模块的粒度要小得多,便于管理和开发。这几种技术中,构件(Component)、服务(Service)就是一种对象(Object),它们的模块化概念比较一致;AOP则是解决系统中的横切问题,把横切相关的解决方案模块化在一个方面(Aspect)中。

2) 抽象 - 这几种技术都是针对某一类具有普遍性的问题提出一个通用的解决方案。但是他们的抽象层次不一样:
业务流程 - Service 是在业务层面上对业务能力的一种抽象,由 Service 可以快速地组装出新的业务流程。
系统架构 - Component 是构成一个系统的元素,可以是具有一定功能的子系统;从系统层面来看架构的话,类级别的对象粒度就太小了,构件的粒度比较合适。
代码 - Class / Aspect 都是在代码这一级别的概念,只是两者解决问题的方法不一样。

看到过一些材村料中有用 UML 表示 AOP 概念的,需要花些时间去研究一下如何用 Visual Modeling 来表示 AOSD (Aspect Oriented Software Dvelopment)。

有兴趣了解 AOP 的话,去 www.ibm.com/developerworks/cn 搜索 AOP@Work 就可以找到很多介绍 AOP 技术的系列文章。


为什么要写文档?

fucunyi | 06 七月, 2007 10:49

很多人一谈起 RUP 或者 CMMI 流程改进的第一反应就是在项目过程中会多出很多文档,那么多的文档岂不是要占用我们很多的时间?这种看待文档的心态一定会影响到流程改进的效果,我们从事的是高科技的创造性工作,为了满足公司规定而写的文档跟自己心甘情愿要写的内容肯定有很大的差别 ,应付了事的表面文章必然是满足不了这样标准化文档原定的目标。我就看到过有开发人员先编码再写设计文档的,基本上就是代码的自然语言翻译,典型的逆向工程。

关键在于怎么样看待文档在软件开发过程中的作用,如果把它看成是开发过程中额外的负担,你就会为了写文档而写文档;如果把它看成是开发过程中自然的一部分,你就会乐于接受它,因为文档就是最终交付产品的一部分。举一个例子,下面的乘法算式中我做了一个简单的类比,原始的运算需求比作是需求,中间的运算步聚比作是设计文档,最终的运算结果就是我们要的目标代码。

如果你能够把设计文档看作是从需求到目标代码的一个中间步骤,你就不再会认为它是一个多余的东西了,相信你也会很乐意地去做它。那我们日常开发中往往又不需要设计文档,大部分情况下的原因就是我们所要开发的软件太过简单了,简单到我们在脑子里也可以完全想清楚;或者是更多的时候,我们只是在原有代码的基础上做一些修补工作,而不需要在白纸上从需求直接跳跃到最终结果。就象这里所举的例子,完全可以靠心算得出结果,但是如果我要让你来手工计算12345*67890的话,相信你一定会利用一个乘法算式来得到结果的。相对于目标代码,设计就是一个介于需求和代码之间的中间产物,它要比需求更接近代码,但又要比代码简单一些。

当然文档不仅只是一个中间过程,文档在开发过程中最主要的职能是“沟通”。 软件开发中最困难的工作是哪一部分呢?我听到最多的答案是“需求”,需求的混乱在于你和客户以及其他涉众之间的沟通不畅和效率低下。对于一个开发团队,最大的挑战来自于团队成员以及涉众之间的沟通,文档就是一种沟通的基本工具。小型的项目,涉及的人员较少,我们可以选择一个轻量级的流程(需要产生的文档也较少);大型的项目,涉及的人员较多,我们可以选择一个重量级的流程(需要产生更多的文档来帮助团队成员之间的交流沟通)。

文档的沟通功能主要作用在横向和纵向两个维度,横向的一方面文档可以使项目成员了解其他相关人员的工作成果,如设计人员需要根据分析人员的需求文档来设计系统架构,所有的项目成员都需要根据项目经理所制定的项目计划来了解各自的开发任务。纵向的一方面文档也是日后系统进行维护扩展的依据,开发人员需要阅读项目以前的设计文档来理解系统结构,然后才能在此基础上对系统进行修改。

几个人的项目,每天碰一次面讨论一下,就可以完成沟通的目的,一个会议记要就可以记录下所有的问题和行动计划, 敏捷过程的代表 XP(eXtreme Programming) 就比较适用于这种小型的项目。对于几十人的项目,这样的沟通方式就不适合了,我们需要一些正式的文档来帮助团队的沟通,如:项目开发计划、软件需求、设计文档、测试计划等等,这些都是为了帮助横向的沟通。在纵向的沟通上,我们更需要一些必要的文档来帮助传递项目的关键信息给将来版本的开发人员。

既然文档的主要职能在于促进团队沟通,我们就有必要制定一些标准来保证沟通的效果。对于同一企业内部的不同项目,我们当然希望每一个项目都采用同样的文档体系,甚至是文档的格式,这样我们从一个项目切换到另一个项目时,我们都能够很顺畅地阅读理解每一个文档。RUP 中就提供了一整套的软件项目过程文档模板。

除了沟通之外,文档也是一种帮助我们整理自己思路的工具。很多想法一旦要落笔记录下来,我们就会更加仔细地考虑其完善性(举个例子,文档的这个作用本身就是在写这篇文章的过程中才想起来并补充进来的);很多在脑海中似是而非的内容也会在文档化的过程被加以细化和规范化。回想一下你从客户那里收集需求的过程,每一个业务人员都只跟你描述他所知道的那一部分业务流程和需求,你需要把每个人的描述都记录下来,然后再综合整理成一个完整的业务流程和需求描述。有些业务处理规则在日常工作并未规范化,可能不同业务人员的理解略有差异,在把这些需求文字化的过程中,我们就会规范这些业务规则,以保证所有业务人员的认同。

文档并不应被误解成一种额外的负担,如果有这样一种感觉,只有两种可能:或者是你没有理解这个文档在整个项目中所起的作用,或者是公司所规定的文档在这个项目中根本上就是不必要的。


如何制定有效的配置管理流程

fucunyi | 06 七月, 2007 10:35

以下是我们在实际工作中遇到的一个例子,这个例子充分说明了正确的工作流程对于保证软件产品质量的重要意义。

1 问题描述

某一开发团队为其客户开发业务软件,系统上线之后存在着很多的业务需求变更,同时也有很多业务部门在使用过程中所发现的软件缺陷,我们把需求变更和软件缺陷统称为变更。开发团队需要迅速响应客户所提出变更请求,把相应的软件版本修复及时地安装到生产系统上去。

为了保证产品质量,该开发团队建立了以下的软件发布流程:

这四个环节分别对应以下四种环境:

开发环境:开发实现客户的变更请求

测试平台:开发团队把软件发布给客户之前做内部系统测试

准生产环境:客户把软件发布到生产系统之前做验收测试

生产系统:最终的生产系统

当开发团队将变更实现提交用户验收测试时,凡是没有通过验收测试的变更将被拒绝,只有通过验收测试的变更才会被部署到生产系统上去。整个流程如下图所示,假设开发团队总共实现了3个变更,其中变更1和变更2通过了系统测试被提交用户验收测试,但只有变更1通过了用户验收测试,最终只有变更1被部署到生产系统上。

为了支持这种工作流程,该团队分别在配置管理系统中管理了四种源代码版本:

凡是通过每一个环节的变更所对应的源代码版本将被复制到下一个环节的版本基线中去。看上去这一流程非常合理,不是吗?

2 质量陷阱

让我们来看这种流程的两个应用案例。

场景I:未经测试的版本组合

在下面的例子中,文件f1f2在修改之前的版本都是1,在实现了变更1、变更2后,它们的版本都变为了版本2,表示为f1(v2)f2(v2)。在整个的测试过程中,前面三个环境上测试的代码版本始终是文件f1f2的版本2,但是最后变更1没有通过验收测试而变更2通过了,那么最终被部署到生产系统上去的版本将是:

f1(v1,这是f1原来在生产系统上的版本)

f2(v2,其中已包含了变更2所对应的版本2)

f1(v1)应该是跟f1(v1,变更1修改以前的版本)相匹配的版本组合,跟f2(v2)相匹配的版本组合应该是f1(v2),由此可能发生的结果是:

在生产系统上运行的是未经测试的版本组合!

场景II:未经测试的版本

在下面的例子中,在前面三个测试环节中,文件f2被测试的版本都是版本4。当变更2未通过用户验收测试时,文件f2最终被复制到生产系统上的版本为3,这个版本是未经测试的。

结果令人难以置信:

在生产系统上运行的是未经测试的版本?!

任何一个软件系统,它的所有代码应该被作为一个整体来进行交付,而不是象上述例子中那样只交付部分的代码(变更相关的代码),这是造成质量陷阱的根本原因。一个看上去合理的流程存在本质的缺陷。

3 改进建议

为了避免以上所述的这些质量陷阱,我们应该改进现有的配置管理流程。

3.1 建立闭环的质量保证流程

选成以上质量隐患的根本原因是系统代码没有被作为一个整体来处理,并且在发布过程中我们发布的是源代码,正确的流程(也是业界较为通行的做法)应该发布构建后的目标码而非源代码。我们可以建立一个闭环的质量保证流程(如下图所示)来批量地进行软件发布。

其中系统测试过程中发现的缺陷应该被开发人员及时改正,然后再做构建,再测试,直到达到一个比较稳定的版本才会发布到验收测试环节。同样的,验收测试中发现的问题也会回到开发环节进行修复。这应该是一个多次循环的过程,不断地发现错误,然后改正,再测试。这个循环到什么时候结束呢?这个取决于各个软件项目的实际情况:

Ø 最理想的情况当然是到所有的缺陷都被改正为止,但是所花的时间比较长,可能赶不上项目的进度要求,现实工作不大可能做到这一点。

Ø 折衷的情况是所有严重的缺陷(即那些影响系统使用的的缺陷)都必须被改正,但允许有一些已发现的缺陷遗留到后面再去解决,前提是所遗留的缺陷不会影响其他变更的实现。大家平时在一些商用软件的新版本中经常可以见到发布说明(Release Notes)中所列的已知缺陷(Known Defects)就是属于这种情况。

我们向开发团队提出这个建议后,马上遭到项目经理的反对:“客户有些紧急的变更需要马上实现并交付生产运营,几乎没有时间来走这样完整的闭环流程。”

3.2 区别对待缺陷和新增功能

通过进一步了解我们发现紧急的变更一般是指影响系统正常使用的软件缺陷,这些缺陷需要及时的修复;而新增功能请求一般不是那么紧急的,允许开发团队有一段时间来开发实现。但开发人员目前是把所有紧急和非紧急的变更请求混杂在一起实现的,往往是一个紧急的缺陷已经修复,但另外一个正在开发中的新增功能也修改了同一组文件版本,造成两者之间的版本依赖,从而导致紧急的缺陷修复不能按时提交。

我们建议把缺陷的修复工作和新增功能的开发工作区分开来,这就涉及到多个版本的并行开发,开发团队主要面临以下三个版本的开发:

Ø v1.0中的缺陷修复

Ø v1.0的新增功能版本v1.1

Ø 下一个版本v2.0

这样缺陷修复和新增功能开发相互独立,保证紧急的缺陷修复不会受到新增功能的影响。

3.3 发布版本构建(build)而不是源代码

在这个案例中另外有一个不附合配置管理惯例的地方是在开发、测试、验收、生产四个环节发布的都是源代码,分别需要构建(包括编译)过后才能部署到相应的运行平台上。由于软件构建的结果很可能会受构建平台及相应编译器版本所影响,最终在生产系统上的运行代码(在生产系统上构建得到)与准生产环境上的运行代码(在准生产环境上构建得到)可能不完全一致,有可能造成质量隐患。比较通行的做法是所有平台上运行的构建代码应该只在构建服务器上生成一次,一次编译到处运行,这样才能保证各个平台上所用到的同版本运行代码是同一次构建的产物。构建服务器通常就是由开发平台兼任,但如果是发布多个不同运行平台的版本的话,可以有多个构建服务器存在,如:同一个软件既有 AIX + DB2 平台的运行版本,也有 HPUX + Oracle 平台的运行版本。

除了某些特殊的运行环境外,如IBM主机系统(mainframe)上明确要求在运行平台上对源代码进行编译构建,一般软件系统的开发都可以遵循这一个工作原则。

3.4 版本发布管理

对于所发布的构建版本,我们也需要进行有序的管理,可以用版本号来唯一标识每一个发布版本。一般可以把用于开发团队内部系统测试的称之为内部发布版本,把提交给客户的称之为外部发布版本,这两种软件发布版本都要统一编号管理。在我们的例子中,内部发布版本可以简单地用构建号来表示,如:

v1.0_build_008 表示版本v1.0开发过程中生成的第8次构建外部发布版本可以由版本号和发布号组合而成,如:

v1.0_rel01 表示版本v1.0的第一个外部发布版本

对于v1.0中的缺陷修复,我们可以通过补丁的方式来发布,一个补丁中可以包含有多个缺陷修复,被修复的缺陷需要在补丁的发布说明(Release Notes)中写明,补丁名称可以由版本号、发布号和补丁号组合而成,如:

v1.0_rel01_p001 表示针对发布版本v1.0_rel01的第001号补丁

对于v1.0中新增功能,我们需要制定一个发布计划,根据客户新增功能请求的紧急程度来分期分批实现,一次发布中可以包含多个新增功能,并且包括所有已改正的软件缺陷,这些改动都必须在发布说明中写明,发布版本号可以在前一个发布版本的基础上递增,如:

v1.1_rel02 表示版本v1.1的第二个外部发布版本

对于下一个版本v2.0的开发,则与版本v1.0开发的发布管理完全一致,如:

v2.0_build_002 表示版本v2.0开发过程中生成的第2次构建

在版本发布管理的流程中,发布版本的安装应该由专门的角色负责,可以是配置管理员或者是集成员(integrator);开发人员被禁止向各平台(测试平台、准生产环境、生产系统)上安装任何软件,并且各平台上所安装软件的版本号台试.0.0 Notes 11都应该有详细的记录。当软件缺陷被发现时,我们就可以明确知道问题究竟是出在哪一个版本。

内部发布版本只会被安装到测试平台上,经过 “开发 à 构建 à 测试 à 发现缺陷à 修改代码” 的多次循环之后,内部发布版本的质量趋于稳定,开发团队才会决定做一个外部发布版本。

外部发布版本被安装到准生产环境上,并且只有通过用户验收测试,它才可以被安装到生产系统上去。如果该版本没有通过用户验收测试,那么开发团队需要提供相应的补丁来解决用户验收中发现的问题,直到通过用户验收后再将该发布版本及其所有的累积补丁全部安装到生产系统上去。有些情况下,最终通过验收测试的也可能是下一个发布版本,所以生产系统上安装的发布版本前后之间不一定是连续的,中间可能跳过一些质量不够成熟的版本。

同样的,只有通过用户验收测试的补丁才会被最终安装到生产系统上去。紧急的补丁经过用户验收测试之后会马上安装到生产系统上,不紧急的补丁可以累积几个以后批量安装上去。

4 ClearCase 工具实现

配置管理工具 IBM Rational ClearCase 可以很好地支持这种并行开发模式。在 ClearCase UCM (Unified Change Management,统一变更管理流程)工作模式中,我们可以在版本v1.0的发布版本基线(v1.0_rel01)的基础上分别创建针对三种版本(v1.0_bugfix, v1.1, v2.0)的开发项目(如下图所示)。 ClearCase 的管理下,这三种版本位于不同的分支上,它们的开发是独立的,互不影响;并且版本 v1.0_bugfix 中的缺陷修复可以及时地合并到版本 v1.1 v2.0 中去,版本 v1.1 中的新增功能也可以在需要的时候合并到版本 v2.0 中去。

ClearCase 也为开发人员提供了方便易用的工作界面 ClearCase Explorer,开发人员可以方便地选择任何一个版本项目来进行开发工作,ClearCase Explorer 可以迅速准确地准备相应的工作版本。所以这三种不同版本的开发完全可以由同一组开发人员来完成,大大提高了开发的工作效率。

5 总结

在这个案例学习中我们看到配置管理流程对于保证软件质量起着非常重要的作用,不恰当的流程可能导致潜在的质量缺陷,开发团队需要根据自身项目的情况来制定一个高效合理的配置管理流程。有了一个好的流程,还需要一个好的配置管理工具来简化我们的管理工作,从而保证开发人员的工作效率和软件质量。


甲方乙方项目管理的差别

fucunyi | 06 七月, 2007 09:49

今天肖勇在MSN上问我甲方乙方项目管理的差别,一时还真不知道怎么回答才好,好象以前也有人问过同样的问题。因为做过的项目的比较有限,只好又举装修房子的例子。这一辈子做甲方的机会不多,装修自己房子时当然我是甲方,装修队是乙方。我做甲方时关心什么呢?
需求:我想把我的房子装修成什么样子?
成本:装修完这套两室一厅需要多少钱?
进度:什么时候装修完工?我好早点搬进来住。
做甲方有两种做法,一种是事事关心,用什么材料、如何施工一一过问;一种是放手不管,到时候来验收就可以了。前者自己辛苦一些,但装修质量、进度、成本都可在自己掌控之中。后者比较省事儿,但意外多一些,遇装修队不淑的话,可能发生偷工减料、装修质量得不到保证的情况。所以管理装修项目时,既可以详细到关心乙方施工的每道工序,也可以粗略到只关注项目的首尾。付出的劳动不一样,得到的结果也往往不同。所以甲方乙方项目管理的差别,完全在于你自己想要什么样的差别。甲乙双方做的是同一个项目,甲方乙方项目管理只是同一个硬币的两个不同侧面。


 
Accessible and Valid XHTML 1.0 Strict and CSS
Powered by pLog - Design by BalearWeb