2006年03月27日

J2EE项目风险

一、概述

当您开始着手一个企业级JAVA项目的时候,您必须对很多方面进行权衡:供应商关系,为保证完整性在设计和开发阶段的过度设计。每个都会带来与生俱来的的一些风险,其中一些是非常明显的,而其他则不怎么明显。但是所有这些风险都是可以避免的。在Humphrey Sheil的这篇文章中,他分析了有可能对企业级JAVA项目的成功造成威胁的10个风险,并且描述了避免方法。

在我当程序员、高级程序员和系统构架师的各个时期,我见证了许多企业级JAVA项目的喜怒哀乐!当我思考到底是什么导致项目失败或者成功的原因的时候,我发现很难找到一个完美的答案,因为为所有的软件项目定义什么是成功是很难的。J2EE项目也不例外。而且,项目的成败不是绝对的。在这篇文章中,我将展示影响企业级Java项目成败的前10个风险,并将他们展示给您。

一些风险会延迟项目的速度,一些则是错误的岔路,另外一些则会使项目完全失败!但是,只要有好的准备、有关的知识储备以及对其有一定了解的知道者,这都是可以避免的。

这篇文章的结构很简单;我将对每个风险按照下面的格式讲述:

风险名称:描述风险的一行文字。

项目阶段:风险发生的项目阶段。

受影响的项目阶段:在很多情况下,风险是影响项目的后边阶段的。

征兆:风险的相关征兆。

方案:如何避免这种风险以及将其对项目的影响降低到最小。

备注:我没有在前边条目中提到的但是必须要提醒的关于风险的一些东西。

我们将在企业级Java项目的重要的阶段检查每个风险。项目涉及到的阶段有:

选择服务提供商:在开始J2EE项目之前选择最好的工具组合-从应用服务器到什么品牌的咖啡。

设计:严格的瀑布方法学模型和“编码然后运行”方法都依赖于设计:我进行足够的设计然后就可以开始开发了。我对设计阶段进行全面思考以保证在开始开发之前我已经思考了所有的问题和解决方案。但是、我并不害怕在这个阶段编码,有时这是回答有关性能和模块性问题的唯一途径。

开发:在这个阶段我们前期阶段的工作的效果将会显现出来。好的工具加上好的设计并不意味着开发阶段会很顺利,但是确实有帮助!

稳定性负载测试:在这个阶段,系统构架师和项目经理要将系统特性冻结,开始关注于构建质量,并保证系统的重要参数指标满足要求-并发用户数,失败次数等。但是,质量和性能不能在前边的阶段被忽略。您不可能写低质量或运行速度缓慢的代码留到以后再去修正。

维护:这其实并不是工程的一个阶段,它只是一个时间段。这个阶段都涉及到了准备阶段。前期的错误(糟糕的设计以及开发阶段对供应商的错误选择)将会显现出对你项目构成威胁。

图一显示了项目各个阶段的不同的风险(特别是对后期造成的风险)

好了,先不管别的乱七八糟的东西了,咱们开始看一看10个最大的风险吧!


二 风险分析

(一)风险1:不懂Java、EJB或者J2EE。

我将逐条分析前面所说的三个东西。

描述:不懂Java。

工程阶段:开发。

受影响阶段:设计,稳定阶段,维护阶段。

受影响的系统特性:可维护性、可量测性以及性能。

现象:写JDK核心API已经有的函数和类。

不知道下面所列的这些东西(下边列出的只是一些例子而已):垃圾收集;什么时候实例会被垃圾收集――悬挂引用问题;Java中的继承机制(或者他们的折衷选择);方法覆盖和重载;为什么 java.lang.String(这里它替代了你喜欢用的类)会导致糟糕的性能;Java的引用传递(与EJB中的传值相比较);使用==与实现equals() 方法这种非初级应用相比较;Java在不同平台上的不同的线程调度策略(例如空闲还是非空闲);绿色线程与本地线程的比较;热点(为什么旧有的性能调节技术否定热点优化);JIT以及什么时候好用的JIT变得不好用(例如不安装JAVA_COMPILER的时候您的代码仍然完好的运行等等);Collections API

RMI(远程方法调用)

解决方案:

您必须加深java的相关知识,特别是关于它的强项和弱项。Java已经超越了语言的范畴。理解它相当于理解一个平台(JDK和相关工具)。具体来说,如果您还没有取得Java程序员认证您必须去取得-您会惊讶的发现您还这么多不了解的。如果把这做为你项目组并且将它推行到每一个人就更好了,而且也更有趣。如果有可能的话家里一个邮件列表来讨论Java技术并且保证它的活跃那就更好了。(我工作国的每个公司都有这样的邮件列表,但是他们大部分由于没有足够的人气而奄奄一息)。向你的开发同事学习――这就是最好的来源。

备注:

如果您或者您的开发团队成员不懂这门语言以及这个平台的话,您能希望您的团队能开发出成功的企业级Java程序吗?高级的Java程序员使用EJB和J2EE将会非常容易。相反,低级的或者是经验不足的程序员则会将J2EE系统弄得质量很差。

描述:不懂EJB

项目阶段:设计

项目影响阶段:开发、运行

影响到的系统特性:可维护性

现象:EJB只被使用一次(特别是返回到等待池衷的无状态会话Bean)

不可重用的EJB

不知道程序员要做什么,容器能提供什么。

不符合规范的EJB(使用线程,调用本地方法,尝试访问IO等等)。

解决方案:

Description: Not understanding J2EE

为了增加您对EJB的知识,请拿出一个周末的时间看一下EJB规范(1.1版有314页)。然后阅读2.0规范以了解1.1规范没提供了什么而2.0提供了什么。特别要注意告诉做为应用程序开发者的您在EJB中怎样做才是规范的做法的那些章节。

备注:

不要从供应商的角度看EJB世界。你一定要了解EJB规范和特定容器的EJB实现之间的差别。这将有利于您在必要的时候将开发经验用到其他供应商(或其他版本)上去。

项目阶段:设计

项目影响阶段:开发

受到影响的系统阶段:可维护性,可扩展性,性能

现象:

一切都是EJB的设计。

使用手动事务管理而不是使用容器提供的机制。

定制安全机制――J2EE平台提供了尽可能完善的集成化的安全构架,从头到尾我们很少用到它的全部功能。

解决方案:

学习J2EE的关键部件以及它们优缺点,并把它们列成表格形式。弄清楚它们的每项服务,记住“知识就是力量”。

备注:

只有知识才能修补这些错误。一个好的Java程序员将会是一个好的EJB开发者。您掌握的J2EE和Java的知识越多,您在设计和实现阶段做的就会更好。这些将会在设计阶段开始显示作用。



风险2:过度设计(使用EJB还是不使用)

项目阶段:设计

受影响项目阶段:开发

受影响系统特性维护、扩展性,性能

征兆:

过大的EJB

开发者无法解释他们的EJB在做什么以及他们之间的关系。

不可重用的EJB、组件或者服务

本应该使用已有事务的时候EJB启动了一个新的事务

为了安全,把数据独立级别设太高

解决方案:

对过度设计的解决方案直接来自于极限编程(XP)方法学。用最小的设计和编程来满足需求,除此之外其他的不考虑。除非你需要明确知道今后可能的需求,如将来的负载要求,或者系统在最高负载下的表现,否则大可不必为系统将来的情况做太多考虑或猜测。另外,J2EE平台已经定义了可伸缩性及出错恢复等特性,可以让服务器系统为你进行处理。

在最小的系统中,系统由一个个小的组件组成,每个组件完成一个单独的工作。这样系统的可重用性得到改善,系统的稳定性也同样得到改善。而且,系统的可维护性得到增强,并且未来新的需求的加入也将变得更简单。

备注:

除了采用上边的解决方案,也可以采用设计模式。它们可以显著改善您系统的设计。EJB模型本身也广泛的使用了设计模式。例如,每个EJB的Home接口都是Finder和Factory模式的例子。远程接口则是真实Bean的代理,对于提供容器的能力也是至关重要的,这些容器截取调用信号并提供诸如透明负载均衡的服务。忽略设计模式的价值将会让是非常危险的。

另外一个我常常警告的风险就是为了EJB而使用EJB。在你的应用中的某一部分可能并不需要EJB,甚至你的整个应用都不需要。这是过度设计所走的极端,而且我确实也目睹了一些良好的servlet和JavaBean应用被重构为EJB,而这样做并没有很好的技术上的理由。

风险3:没有将业务规则和逻辑表现形式相分离

项目阶段:设计

受影响项目阶段:开发

受影响系统特性维护、扩展性,性能

征兆:

过大的没有边界的Jsp

您发现您在业务逻辑发生变化的时候在编辑JSP页面。

显示上的改变迫使你修改并重新部署EJB和其他后台组件

解决方案:

J2EE平台使你有机会将表示逻辑和导航控制相分离,进而与业务规则相分离。这叫做Model 2框架。如果您已经陷入这个陷阱,您可以使用重构。

备注:

可以使用具有一致性的设计来进行用户界面框架的连接(例如taglibs)浙江有助于您在您的项目中将业务规则和逻辑表现形式相分离,不需要您创建一个新的GUI框架,现在已经有很多稳定的实现。对他们一次进行评估,然后选出一个最符合您需要的框架来。

风险4: 没有在开发环境中进行适当的配置

项目阶段:开发

受影响的项目阶段: 运行、并发、成熟期

受印象的系统特征:你的权衡

征兆:

经过多日或数周的时间才能过渡到成熟系统

风险存在与过渡期,带有很多不确定性,有些主要的功能场景没有被测试到

实际系统中的数据和开发、测试中的数据不同

无法在开发者机器上进行组建

应用行为在开发、稳定化及产品环境中各不相同

解决方案:

风险4的解决方案是忠实地在开发环境中配置实际的环境,让开发所用环境接近于要实施产品的环境。如果客户的运行环境是JDK 1.2.2和Solaris 7,那么不要使用JDK 1.3 和Red Hat Linux进行开发。而且不要在一个应用服务器开发而在另一种应用服务器中运行。使用实际产品的数据进行测试,而不要依靠于手工录入的模拟数据。如果产品数据很敏感,则要使之变得不敏感,然后把它配置起来。开发中未能预期到的产品数据将对以下过程产生破坏:

数据校验规则

系统测试行为

系统组件构建(特别地包括:EJB-EJB以及EJB-数据库)

最为糟糕的是,这样还可能产生异常、空指针,以及你从没见过的问题。

备注:

开发者常常将安全问题留到稳定阶段才解决(程序界面很好的运行,我们现在加上用户校验的东西吧)。要防止这样的陷阱产生,你也可以花费同样多的时间在业务逻辑中改进安全性。

成熟期是一个复杂的过程,其中充满了各种非技术的和技术的问题。你可能会陷于想不到的一大堆问题中,这就是成熟化所意味的一切。开发及稳定化环境过程为你提供了制造更多这样的问题,以及发现这样的问题的地方,不断去做,就可以大大减少风险。

你做的工程越多,你就越能了解什么是可行的,什么是不可行的。你可以对工程问题进行记录,以避免同样的错误重复发生。

风险5:选择错误的供应商

项目阶段:供应商选择

受影响项目阶段:设计,开发,维护,测试,运行

受影响系统特性:性能,可维护性,稳定性。

征兆:

开发者花费大量时间跟开发工具脚劲而不是使用他们进行高效率的开发。为了解决已知的或未知的Bug,系统需要重构,并且不同的开发工具几乎无法整合(应用服务器和IDE,IDE和调试器,源码控制和构架工具等等)

对于IDE,调试器等,开发者会赞同使用他们喜欢的工具。

解决方案:

为了避免风险5,您需要一个好的供应商选择流程,风险10也适用于此。

对于IDE,唯一的评估它的途径就是使用它。评估J2EE实现的唯一途径就是构建一个试验并对您关心的系统的特性进行试验。您肯定不希望您花费了3个月时间开发并进行了培训后才发现系统有很多的bug。

如果在开发过程中,您对您的工具集有疑问怎么办呢?当然一些工具肯定会比另一些表现好。如果你现则了不满足您要求的应用服务器,那么请吸收它然后修改开发规范。如果IDE不好用,请降低代码标准(使用制表符还是空格)。让开发者选择使他们更高效的开发工具。

备注:

要知道最好的供应商和工具不是对一个特殊任务的一次性工作。您要经常进行市场评估。例如,我在过去的12个月中使用了四个不同的IDE,这依赖于我的应用服务器、平台还有是否编写EJB。

风险6:不了解供应商

项目阶段:供应商选择

受影响项目阶段:供应商选择之后的所有阶段-设计,开发,维护,测试,运行

受影响系统特性:可维护性,可扩展性,性能

征兆:

开发时间比预想的长了超过33%,开发者重新发明轮子――开发供应商已经提供的需求的特性。

解决方案:

为了避免不了解供应商造成的风险,订阅所有供应商提供的资源,您可以在邮件列表、新闻组和版本备注(特别是已修正的bug列表)中得到您评估需要的信息。

一旦确定了供应商,请尽快开始培训,在项目开始前越早越好。下一步,构建一个快速模型来证明,从而打消开发团队的顾虑。构建EJB并部署它们,然后在表达层(Swing GUI, JSP等等)中调用他们。如果您在进行系统开发的时候才进行开发环境的搭建,那么环境搭建常常会造成麻烦。我看到过这样的项目,他们没有一个构建流程,“我们没有时间了”。当团队必须工作到11点的时候表现的更为明显,每晚他们只是将程序拼起来然后运行。磨刀不误砍柴工-这样做会节省你很多时间。有人会说“我们计划中中没有安排这个时间”,我说“您的计划中没有不去这么做的时间”

备注:

不同的供应商对J2EE的特定的实现技术是不同的。让我们看看一个两个供应商的例子:IBM和BEA。IBM采用图形化的WebSphere环境,恰恰相反,BEA则为WebLogic提供很多的命令行工具。IBM的WebSphere使用IIOP进行通讯,并抛出CORBA异常(对程序员非透明),WebLogic则没有采用CORBA底层构架而是默认使用t3协议。

WebSphere与Visual Age是紧密结合在一起的,而Weblogic则是可以使用多种IDE的。您可以使用几乎任何IDE进行WebLogic的开发。

他们之间是还是有不同点的。你是一种应用服务器的专家并不意味着你是其他应用服务器的专家。上述各点体现在各个方面:IDE、调试器、构建工具,配置管理等等。在一个特定工具上熟悉的人可以在评估该提供商的竞争对手产品时具有一些便利。但是这并不意味着您可以把程序在不同程序之间进行无缝链接。因此,您必须花费一些时间来熟悉这些工具。

风险7:没有考虑可扩展性和性能

项目阶段:设计

受影响项目阶段:可扩展性,性能,可维护性

征兆:无法接受的慢速的系统(不应该服从重构)

服务器端被很强的负载所压迫,导致不能充分发挥集群技术的全部优势。

解决方案:

在这个风险中,我们接近我们系统性能的可扩展性需求-我们在您开始开发之前要知道您需要什么参数。如果您需要每秒50个并发事务数,而您的实体Bean只能提供40个,那么您需要寻找其他可选的解决方案,例如存储过程、批处理或者重写联机事务处理系统。

您要让供应商参与到系统性能需求中去――他们知道他们产品的强项和弱项,这样可以对您有相应的帮助。

备注:

没有为可扩展性和性能进行设计看起来与第二个风险(过度设计)相冲突。实际上他们是互为补充的。对于风险2我提倡只实现真正需要的功能。通过说明性能和可测试性要求,您可以设定需求的上界。

如果您认为可扩展性是一个重点要求的话,您就需要首先选用一个带集群支持的应用服务器,可能还需要一个事务缓冲池支持。您还需要象EJB这样的业务组件引擎,因为您可以充分利用服务器的系统构架。在这一点上极限编程将不会有任何问题,在极限编程中系统是用来满足客户的功能和行为要求的。

风险8:缺乏开发过程控制。

项目阶段:开发

受影响阶段:维护,运行

受影响系统特征:可维护性,代码质量。

现象:

项目计划看起来象瀑布模型:首先根据草案设计系统,然后我们就坐下来开始漫长的编码。因为构建过程不存在,所以构建成了一个梦魇。构建的日子也就是停止开发的日子,因为我们什么都没得到。

组件在集成之前没有经过足够的测试。集成测试意味着将两个不稳定的组件捆在一起,然后到调试器的堆栈树中去观察他们。

解决方案:

一个好的软件方法学将会节省您的生命。我已经提过了XP;在参考资料章节中我给出了相关的站点。在那里您会对XP有更深入细致的了解。

备注:

我无法想象我不使用Junit进行单元测试和Ant进行构建的日子(这两个免费工具支撑着XP方法学)。如果想了解更多关于Junit和Ant,请参考资源这一章。

风险9:使用框架失败

项目阶段:开发

受影响项目阶段:开发、维护、运行

受影响系统特征:维护性,可扩展性,代码质量

征兆:

核心类库中的Bug在代码中多次使用

没有设定日志标准,所以输出不能此采用脚本进行读取和分析

错误的或不协调的异常处理。我再有的站点看到,终端用户可以看到系统的低级错误;例如当用户要将他们购物车中的商品付费的时候出现一个SQLException 的stack trace。用户应该怎么办呢?难道要求他给数据库管理员打电话,然后要求他修改主键约束错误?

下面的任务必须以某种方法进行处理,并且要成为任何构架的第一目标:

日志:

异常处理

夺得到某些资源的连接(例如数据库、命名服务)

构建Jsp 页面

数据校验

解决方案:

我对轻量级框架非常情有独衷,实际上,我在JavaWorld上的第一篇文章就是《框架节省时间》,它讨论的就是企业及Java环境衷的框架。如果您已经在开发了,那么通过使用一个框架您仍然能够收获颇丰。在重做这些东西的时候,您将会遇到诸如错误处理和日志之类的错误,但是从长远来看这会大大节省时间和金钱。

备注:

当在选择框架和基础组件开发的时候,您必须思考他们的不同的重用级别。第一级别的重用率时0.9甚至更高,也就是说项目中90%将会用到它。

风险10:项目计划和设计建立在市场炒作上,而非实际的技术上。

备注:一开始我没有把风险10加上来,后来我发现很多人都对企业级Java有误解,特别是对于刚刚解除这个领域的人。

项目阶段:所有受影响的阶段,特别是供应商选择阶段尤甚。

受影响项目阶段:所有阶段。

受影响系统特性:可维护性,可扩展性,设计质量,编码质量。

征兆:

因为EJB是可移植的所以在技术选型方面不重视。

在供应商选择时没有进行产品试验

在项目生命周期衷需要更换开发工具。

解决方案:

别轻信项目外任何有即得利益人得说法。也就是说:不要轻信供应商(除非您对他们非常了解),不要轻信白皮书(因为他们是供应商花钱买的)。如果您需要真正得建议,那么请查找关于它得相关评论。甚至,可以下载您想评估得工具,在上边试着开发一个小的系统原型。不要运行工具中自带的例子(每个好一点的供应商都会加上这个)。

为了概括总结,花一定的时间为您的项目选择正确的供应商和工具集。缩小您的选择范围到三四个供应商,然后进行测试。对您选择的IDE、应用服务器进行为时一周的测试和构建。熟悉您将要用来开发项目的工具。

三 总结

只有这10个风险需要注意吗?

10只是一个武断的与其他风险分割开的数字而已,还有很多其他的风险。我就能说出很多。但是即使如此,如果您能说出我这列出的这些风险,我就可以保证您的项目会非常优秀而且必定成功。

如果还有我不想让您独这篇文章的原因就是:这不是经验和计划的代替品。如果您没有经验,那么请去积累。不要依赖项目开发中的培训会起多大的兆月年个。在开发前请做好心理准备。请Java和J2EE指导者对你们团队进行全程指导、把握项目方向,并和较少经验的团队人员一起成长。

最后,我写的越多我想到需要说的东西越多:

软件工程的社会因素

单元测试与集成测试(什么时候进行测试?)

设计模式

异常处理

唉,不能再写了。等待着新文章吧,祝君好运!

结论:

这里列出了10个风险,他们能够概括您进行企业级java开发的时候遇到的大部分问题。我坚信,您在开发过程中,还会面对很多其他的缺陷,但是我也坚信我已经概括了主要的问题。我们翻个个,将10个风险按着优先级排序:

不懂Java,不懂EJB,不懂J2EE

过度设计(使用EJB还是不使用)(设计模式)

没有将业务规则和逻辑表现形式相分离

开发时没有部署

选择了错误的供应商

不了解您的供应商

没有设计可扩展性和系统性能

陈旧的开发过程

没有使用框架

项目计划和设计建立在市场炒作上,而非实际的技术上。


本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月21日








大道无形——有效软件工程初探


我们是软件工程的实践者,而不是高高在上的布道者


我们信奉的理念是:大道无形,有效的才是最好的


大道无形——有效软件工程初探
(暨“有效软件工程实践(网)”揭幕告白)


http://www.effective-swe.com/


一个学生和N个老师——关于过程的困惑


    当今的软件过程领域可以说是热闹非凡,SW-CMM在咨询公司的大力鼓吹和政府的扶持下在大江南北遍地开花,让那些够格和不够格的咨询公司们忙了个不亦乐乎,即使SEI推出了最新的CMMI,由于其一脉相承的血统,丝毫没有减弱业界对其的热情。虽然其在国内的实施效果已经越来越多的受到各方的质疑,但作为一种重量级的过程模型依然在业界保持着绝对的权威地位。
    
    2001年的春天,一群软件拥有相同理念的过程专家们齐聚一堂成立了所谓的敏捷联盟(Agile Alliance),这些人中为首的便是Kent Beck,其在5年前(1996年)就提出了一种轻量级的软件过程——极限编程(XP)。无论是作为一种理念的敏捷编程,还是作为一种可操作的软件过程的极限编程,自从其被引入中国那一刻起,就以其自由的风格和饱满的热情深深的打动不少软件从业人员,尤其是基层的程序员和中小项目的管理者。
    
    Rational 统一过程(简称RUP)作为一种用例驱动、以构架为中心、迭代和增量的开发过程,随着UML的推广和普及也渐渐成为一种主流的开发过程,前段时间其开山鼻祖之一的Ivar Jackbson高举着Smart的大旗来到中国传播其“主动软件”的理念,又令业界一时间陷入了 关于“隐性知识”和“显性知识”的热烈讨论中。
    
    从业界的大师们到咨询公司的咨询师们再到这些理论的忠实拥护者们,几乎每个人都万分诚恳的对你循循善诱的摆出一大堆充分或不怎么充分的理由,往往同时还都能列出一个能够有力证明某个模型优越无比的对比列表。所有人的目的只有一个:那就是告诉你唯有他所推荐的模型才是最适合你的。于是乎我们陷入了深深地困惑:到底什么样的过程才是最适合我们的呢?而且,在大多数情况下,当我们满怀崇敬的遵循大师们为我们指引的过程小心翼翼的前行,却发现其终点却远非其描绘的那么的美妙。于是乎,这种困惑变成了一种痛苦。
    
    当然,大师们总是高高在上且充满智慧的,但当他们给我们指引的道路变成一种痛苦的时候,我们就有理由来反思一下我们走上这条道路的理由是不是那么的充分和必要。



把书翻过来——看看文字背后的内容


    当年鲁迅先生从满纸的道德文章后面看到了“吃人”二字,从此让我们学会了原来念书是可以这样念的,今天我们不妨用鲁迅先生传授我们的方法看看这些深奥的过程背后到底是些什么….
    
    首先,有一点是显而易见的,那就是软件开发的管理对任何人来说都是一个绝对的挑战。在这个领域里面,人似乎都是无比的弱智,虽说是条条大路通罗马,但我们似乎永远不能一开始就找到通往罗马最快捷的道路,一没人指点,我们就要在南北极无谓的打N个来回,所以我们必须学习前人们通过无数失败总结出来的成果。虽然前辈大师们给我们指点的通向罗马的道路也分为各门各派…


 


    然后我们沮丧的看到一个事实:人是不可靠的,正因为人是不可靠的,我们需要用各种各样的方式来验证我们的工作成果,以尽可能的发现缺陷,并及时的修复,其实大师们说的都是一件事情——验证。虽然承认自己的无能是令人沮丧的,有一定是肯定的,那就是:我们需要有效的验证自己的工作——无论是行为还是结果,至于形式是次要的。


 


    再看下去,我们会发现软件开发在绝大多数情况下应该是个群体行为。所以我们需要沟通和传承,无论是CMM过程中庞杂的文档还是XP中颇为极端的“结对编程”其出发点都是为了沟通和传承,虽然无论是无休无止的编写文档还是两个人坐在同一台电脑前的吵吵闹闹听起来似乎都不能令人心情愉快,但不管怎样,有一定是肯定的,那就是:我们需要有效的沟通和传承,至于形式是次要的。


 


    接着往下看,我们会发现,人是健忘且判断能力低下的,所以我们要量化的记录我们的所作所为,这不但可以有效的展现我们的工作业绩,更是让我们避免多次掉入同一个坑里。 但不管怎样,有一定是肯定的,那就是:我们需要有效的用量化的数据来度量我们的工作,至于形式是次要的。


 


    继续往下看,我们会感觉些许的不安,那就是我们会发现这个世界的万事万物是不断变化的,而且其变化的迅捷常常让我们疲于奔命且晕头转向。关于这一点,大师们给我们指点的无非是我们老祖宗——大禹及其前任们治水的那两招:“堵”和“通”,这里的“堵”并不是指完全的拒绝变化——这是不可能的,而是指将所有的变化处于完全受控的状态,CMM应该是这种方式的代表,其通过建立一套复杂而庞大的控制机制使所有的变更都处于受控状态,然而这个美好的愿望却时常因为其笨重的身形和高昂的成本令人不堪重负而无法有效的执行。相对而言XP提出的“拥抱变化”采取的是“通”的策略,这听起来颇为令人兴奋,至少和繁杂的过程以及成堆的文档告别是一件让人心情愉快的事情,但实际操作起来往往并不那么容易,除非你是“大禹”那样的绝顶高手,否则弄不好就会溃堤决口、水漫金山。虽然上述两条路听起来都不怎么美妙,但非常遗憾我们目前还没有第三种选择,个人认为最有效的方式也许应该是首先看清楚是一条什么样的河流,然后再判断哪种方式更为合适,而在某些情况下,将“堵”和“通”结合使用会有意想不到的结果。但不管是采用什么方法,有一点是肯定的,那就是:我们必须找到有效的方法来应对变化,至于形式是次要的。


 


    所谓“仁者见仁,智者见智”,我相信不同的人遵循着这个方法可以看到更多的东西,但有一个结论是肯定的,那就是我们行为的最终目的是要达成我们的目标,至于确定采取何种行为的标准应该是该行为针对某个特定目标的有效性,而不是它的形式,更不是因为它曾经出自于某个大师。



小结


 


    时下有一个非常时髦的名词——“驱动”,诸如目标驱动、用例驱动、过程驱动、方面驱动、测试驱动、业务驱动……一时间好像所有人都被这个或者那个驱动得团团转。其实我们在满怀崇敬的拜读大师们的理论和方法的时候,不妨深究一下“驱动”这些理论和方法的东西是什么。任何理论的产生都有其特定的背景和环境,正如“南橘与北枳”的故事一样,一味的照搬别人的东西往往并不是通往理想彼岸的最佳途径,所以我们不光要知其然,而且还要知其所以然,只有这样才能有效的找到真正适合自己的有效的方法。


 


    也许我们都曾经或多或少的受缚于某位大家的理论或某个权威的模型,但这并不妨碍我们用自己的智慧来探询真正有效的解决方案,相反,没有曾经的作茧之缚,也就没有破茧之后蝴蝶的美丽和灿烂……



 


行者无疆
Nov. 29 2005


mail: TheWalker@effective-swe.com
MSN: just_a_walker@hotmail.com

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”








我是这样领导一个学生项目的

作者:Peter Cheng 来自:Peter Cheng的Blog

没想到在小组成立的第八天才想起来该为这个项目记下点什么,不是开发设计文档,也不是使用手册或者项目进度表,而是为了我自己的一些回忆。这是我领导的第三个软件开发项目,真正意义上的应当是第一个,因为这次是软件工程课程的实践项目,相比而言以前的两个只能算是体验软件开发的一些经历而已。同样的,作为真正意义上的Leader,或者PM(项目经理Project manager),我还是个新手。毕竟,软件工程这门课刚刚开始五个星期,区区十五个学时还不能带给我一些什么,因而我努力阅读了大量的书目去丰富我的知识体系。我希望这个项目能够获得我期待的成功,至少这门课程的结业成绩能够让我满意,仅此而已。当然,如果能积累下宝贵的丰富经验那便是额外的巨大收获。


过去的一周让我充实,我从未如此大量的阅读书籍,在过去的七天中,我翻阅了近十本软件工程相关的书籍,它们大多是经典的和有效的,大约六本我仔细钻研了每一个细节,剩余的我循着前人的笔迹也汲取了足够的精华(这些书大多来自图书馆,感谢那些喜欢在书上乱涂乱画的前辈,是他们给我勾勒出了重点)。很难说我究竟学到了什么,技术上的也许没有,或者思想上的本就可以形式化为技术,那我的收获是丰富的。让我寄予期望最多的是著名的《人月神话》,这个书名让我的许多朋友误以为是小说的东西(事实上,人月指的是工作量,月指month),的确是那样迷人。如果说这本书与其它的书籍有什么区别,那就是:我阅读一般的两百页的书籍能够大约为其中的六七个闪光点而激动得手舞足蹈,而这本书有超过十次让我兴奋地从公交车上跳了起来(我不鼓励大家在公车上阅读,对视力的影响的确很大,尽管这是节省时间的一个有效的方法)。我要说的是,仅此而已,毕竟这是一本几十年前的书籍,尽管在它二十岁生日的时候再版过(这也正是我所阅读的版本),然而它并非是专为软件工程而设,尽管被软件工程领域的专家们奉为圣书。

我的这个小组共有五名成员,很多项目经理不愿意将自己记入到成员数目中,一个典型的说法是:我们小组由我以及另外四名成员构成。这会使得项目经理变得孤立,特别是人人都对上司有天生的反感的情况下,这种现象并不仅仅出现在中国。在上一次的OOP(面向对象项目)中,有三个骨干成员保留到了现在的小组,另外两个中的一个是同样出色的一名成员,也是小组中唯一的女生。最后的一个是一个不折不扣的新兵,是一个还不知道OO为何物的初学者(也许这样说有些自大,似乎我们已经清楚什么是真正的OO一样)。他的加入是一个偶然,纯粹是出于哥们儿义气,这也是大多数学生项目会遇到的问题之一,你不得不去面对一些你并不愿意一同合作的搭档。如何将这样的五个人捏合在一起将成为我们的项目成功的关键。在人面前,技术将变得索然无味,记住这样一个事实,项目管理是面向人的。于是我不得不花去相当多的时间帮助他通过Java来入门,这缘于我对Java的热爱以及Java很可能成为我们的开发语言这一事实(请记住,永远不要做无用功,争取让你现在做的每一件事都可以成为将来迭代的一部分)。

不要以为开会是一个不好的习惯,适当的会议是必要的,甚至是强行要求的,因为它可以让你的项目受益,我们为什么不适当进行会议呢。我的工作就是从第一次会议开始的,一个惊人的举动就是我决定在今后所有的字面文档和口头交流中都使用英文,为此我们进行了尝试,第一个吃螃蟹的人总是弥足珍贵,你的项目中需要有这样一个人,他有足够的能力,并且愿意尝试新鲜事物,不惧怕枪打出头鸟的传统观点。庆幸的,我们有这样一个组员(多使用“我们”而不是“我”,是每个项目经理应当养成的良好习惯)。于是,英文的交流顺利地展开了,尽管大家还有些约束,特别是那个新兵的四级考试还没有通过,着实让我汗颜。然而,轻车熟路之后一切都没有了障碍,单词成为了我们交流使用最多的单位,而不是句子。

第一次会议是轻松的,不要指望能通过这次会议得到些什么,这是一次互相熟悉的会议,彼此需要互相熟悉习性、说话的习惯、喜欢的零食甚至迟到的时间,对于一个项目经理,掌握这些更为重要,我无意重复实践的重要性,实际情况的反馈往往是制定今后计划和策略的基础,也是最直接的来源,然而不幸的是,没有人可以为你收集这些资料,你需要做的是默默记在心里,然后转为今后的行动依据,一些估算往往由此而来。

我们确定了文档的重要性,尽管文档驱动被更多的书籍称作软件开发的黑洞,一些专家认为文档仅仅是官僚主义的作风,当然没有人否认适当的文档是绝对必要的。什么样的文档应当生成呢?你需要将今后可能查阅的资料组织成文档,时刻告诫自己文档是面向未来的,而不是面向过去。单纯的流水账似的总结没有意义,附加上从中获得的经验教训才是这类文档的灵魂。

还有可笑的预算机制,对于学生项目而言,没有明确的所谓客户的概念,没有人会为你的付出买单,所有的开支都是有去无回的,对于许多并不富裕的学生来说任何的开销都倍加重要,请记住,没有一个一天只能吃一顿肉的孩子会为了打印一百页纸而花去四十块钱,他们更宁愿选择手抄。庆幸的,我们的小组成员虽然不能称得上富裕,但至少可以经常在菜盆中发现牛肉的痕迹。我们的预算(budget)机制很简单,也许称之为报销(reimbursement)机制更为合适:每个人先交十块钱给CFO(首席财政管,我们经常为起了这个名字而感到乐趣),也就是当然不让的那个女生,然后项目总结时一并从中报销开支,多退少补。就像许多班级收班费一样,简单的往往是最好的,因为它易于被最多的人接受。会议在轻松的气氛中结束,伴着混沌和锅贴的香味,看来选择食堂作为会议地点是一个不错的决定,因为这里足够嘈杂,不会让大家觉得拘束而不敢说出真实的想法,即使冷场也可以借用咀嚼的声音来打发无聊的时光。一个更现实的原因是,我们找不到其他的地方能同时拥有灯光、场地以及大声说话的权利了,我们没有会议室可用。请记住,这是一个学生项目。

第二次会议在一周之后举行,也就是昨天(还记得吗,我是在小组成立的第八天记录下的这篇文章)。一周以来,我明确了一个思想:项目经理必须和首席架构师分开,哪怕是四五个人的小型项目。这得感谢《人月神话》以及其他的软件项目管理的书籍(他们大多来自于机械工业出版社的软件开发技术丛书系列)。在以前的两个项目中,我都将项目管理和系统开发以及首席编程和测试融为一身,以至于曾经一个组员反问道:你都做完了还要我们干吗啊?的确,明确的分工是必要的,用人不疑,疑人不用。一个成功的项目经理应当懂得如何将工作交给适当的人去完成,而不是独自去完成所有的事。于是,我决定由另一个人来担任首席架构师的角色而不是我自己,这在我看来是一个破天荒的决定(尽管有些可笑),很多人(特别是学生和一些积极性不高的人)都会认为技术最好的人理应当成为项目经理,这也许也是我成为项目经理的原因,然而事实上要记住的是,项目经理是管理人的,而不是管理技术的,他所要做的仅仅是辅助首席架构师完成协调的工作,技术的事还是交给别人去完成吧。

我在图书馆花去了五个小时翻阅了几乎所有关于软件工程方面的国外书籍(不是我对国内的书籍作者有偏见,然而确实国外的教材要优秀的多,当然国内不乏鼎鼎有名的作者和同样鼎鼎有名的著作),从需求分析、设计到质量保证、配置管理,还有CMM,等等一切。我选出了九本书籍作为我们项目的主要参考书目。我为我们的小组设计了五个领导人(感到奇怪吗,我们一共只有五个人而已),分别是需求经理、首席架构师、质量保障经理、测试经理以及项目经理,也就是我自己。九本书的一本是所有人都必须阅读的,另外我为其他每个人选择了相关领域的各两本参考书,我认为它们是可获得的、经典的和有效的参考书,这是我五个小时的全部结晶。在每个阶段或者说每个领域,都会以特定的人为中心,其他人接受他的指派完成任务,这样做的好处是利用有限的人员让每个人能够尽可能多的体验到软件项目的所有阶段,请记住,这是一个学生项目,学习是第一位的。为什么要我亲自去选择参考书,因为我的时间比他们富裕,我免修了本学期的三门其他课程,因而我能够有足够的时间去做这些事情,同时,选择书籍的过程也是自我提升的过程,何乐而不为呢。

终于有人在第二次会议迟到了,直到我们收拾东西准备离场时才出现,后果就是我们已经分完了所有的职位,她没有选择地成为了需求经理。这并不是什么坏差事,然而对于这样的学生项目,没有真正的客户是一个很困难的问题。需求经理需要有强烈的自虐倾向,需要自己扮演客户、最终用户和需求分析师三个角色(如果你还不清楚客户和最终用户的区别,那太糟糕了。客户是出钱的人,用户是实际使用软件的人),这种经历恐怕是绝无仅有的,试想,一个人需要自己不断给自己出难题,然后去解决,太可怕了。那个新兵选择了质量保障经理,因为他认为这是个轻松的职位,不用太多的编写代码,他讨厌程序设计。事实上,我可以想象当他面对一大堆模型的时候他的反应。在软件项目中,如果你认为某一个职位是轻松的,那唯一的原因是你还没有真正理解这个职位的作用。

会议中我最后强调的是,每个人都应当适时地召开会议,并非只有项目经理才有权召开会议,如果必要,任何人都可以这样做。另外,软件项目不是生活的全部,每个人应当将更多的精力放到生活中去,比如陪伴自己的家人,或者处理其他学业,这仅仅是一个项目,是诸多生活元素中的一部分,仅此而已。

一周中我最大的工作是完成了项目计划的草案,这得益于我阅读的几本书籍,当然还有Rational SoDA,这是一个很棒的文档自动化工具,它的文档格式成为了我的设计标准,甚至教会了我许多Microsoft Word的使用技巧,比如自动生成目录。这份草案没有任何实质内容,仅仅是标题性的搭建了框架,所有的内容将在一周之内填充,为什么?因为我们还不知道项目的题目,除此以外的一切都会是徒劳。良好的准备是必要的,在组织任何文档之前都应当先建立模版或者框架,接下来的工作才是用内容去填充框架,而不是线性的编写过程。

也许我还做过许多别的事,然而八天的缘故已经难以一一记录,有一些大概已经在脑海里永远冬眠了,甚至我自己都难以提取形成文字。庆幸的是每个人同样可以获得这些,只要愿意去阅读一些经典的书籍,总能得到。

现在我能做的就是静静等待项目题目的出现,还有学习RUP,三个月之后项目交工之时我大约能够读完软件项目最经典的一百本书籍,这会是我最大的收获和骄傲。我喜欢从阅读中得到满足。

项目正式启动了,因为我们获得了一个导师推荐的题目,这是一个realty system,之所以推荐是因为它和Rational Rose教程中的例子是一样的,因而对于初学者而言有很多可以直接参考的UML模型,事实上,掌握UML是这次课程的重点。然而我们并没有打算做这个题目,因为我们不想依靠太多现成的东西,和更多的组撞车不是一个好主意,更重要的,我们既不能和现有模型太过相似,显然至少不能比它还要差,然而事实是这个模型已经相当完善了,我们没有了发挥的余地。于是在每周例会上,我们决定重新找一个题目。周例会也变成了每周两次,这样做是必要的,因为在开发的前期准备阶段,我们需要很多的时间来达成一些共识作为今后的行动准则,这同样可以营造出良好的讨论氛围和融洽的合作关系,为后面的开发做好铺垫,而这一阶段的文档要求并不高,工作量不大,有足够的时间来讨论。

不知道算不算一个明智的决定,我在题目决定之前就分发了风险组织的任务,因为我相信对于大多数项目而言,大多数的风险是相似的,这种相似包括可能性和影响级别,当然还有风险类别。也许80-20准则是适用的。现在看来这个决定暂时是明智的,因为在这个阶段我们没有太多的事可以做,或者说没有太多需要形成文档的工作。我们需要时刻保持对文档的熟悉,所以安排在这个时候做风险分析是合适的。我给出了一个模版,要求我们每一个人给出至少30条风险,其中至少有10条是和自己的角色相关的(比如测试经理必须给出10条与测试密切相关的风险),这样做一方面可以让各人更加熟悉自己的角色,同时也让各自风险雷同的几率小了很多,我们有更多的机会找到更多的风险。很快地,反馈回来了,这是第一次让我得到满足的反馈,Review Manager负责将这些风险组织起来,去掉雷同的并给出适当的翻译,可能会很奇怪为什么要这样做,我们一再要求所有的文档必须英文化,为什么还要多此一举把它再翻回来呢,因为在这些风险中,很多是来自于一些中文资料,每个人将它们用自己的英语生硬地翻译成英文之后提交了上来,面对那些蹩脚的英文或许翻回中文再阅读比较合适,当然最后还是要重新翻译成英文的。很快地,我们总结出了大约80条风险,去粗取精之后剩下了50条,形成了最终的风险表。不可能也没有必要对所有50条风险都做监督管理计划,我们选择了其中的30条形成各自的RMMM(Risk Mitigation Monitoring and Management,风险缓解、监督和管理计划),每个人负责6条的编写,当然都是和各自的角色密切相关的6条风险,所选择的风险或者发生可能性高同时影响也不低,或者尽管不大可能发生然而一旦发生后果很严重,它们都被列入了风险表并进行管理。同样地,伴随着分发的任务还有一份我制作的RMMM Template,需要说明的是,作为一个学生项目经理,最好能够尽可能多地给出各种文档模版给大家使用,因为我们并不是总有很多现成的模版可以使用,而事实上很多人不是很愿意去寻找模版,所以比起之后再统一格式,一个好的选择就是尽早地分发模版,当然,这要占用项目经理的很多时间。

主题的决定是艰难的,尽管否定了老师的推荐主题,我们仍然没有确定合适的替代者。我的建议是一定要围绕数据库开发,这样的好处是我们可以形成更多地UML图表(主要是类图),这也正是导师的初衷,主动去迎合他不是很好吗。于是,锁定在信息管理领域成为了第一个确定的范围。关于足球转会系统的设想失败了,因为我们的Requirements Manager(也就是那个唯一的女生)对足球不感兴趣,的确,很难想象让这样的角色去做不愿意做的事情,那对项目的损害是灾难性的。另一个提议是学生信息管理系统,或者通俗地讲就是做一个教务处系统,这是被我否决的提议。试想,这样一个系统导师和其他同学太过熟悉了,一旦包含任何的缺陷(这是必然的)很容易就会被发现,对于学生项目这是一个糟糕的主题。最后的选择是酒店管理系统,主要是面向前台的订房系统,这来源于需求经理的强烈兴趣,有时候非原则性的相互妥协是必要的,它可以激发团队的工作热情,更何况这是一个的确很不错的主题,因为它需要一定的专业领域知识,在一个项目中涉及到适当的专业知识可以使得需求范围进一步缩小,需求更加明确,同时可能会有比较多的现有系统来参考。不容忽视的是,并非每个同学和导师都会对这些领域的系统相当熟悉,也就容许了一些缺陷的偷偷存在。

我曾经试图将项目计划中的活动计划分发给每个人去完成,然而几经考虑之后不很合适,因为现在已经有太多的事情要做,为了保持团队的活力(一个重要的原因是我的课比起他们要少得多),我决定独立完成计划,当然这期间每个人仍然有自己的任务要完成,不要让任何一个人闲着,因为这表明对他的不信任和对他能力的低估,每个人都适当忙碌对大家都有益。项目计划也是有现成模版的,感谢Rational SoDA的模版,当然还有我综合各种文献进行的修改,使得文档的结构相当完善,好的结构是进行文档创作的第一步,需要再次强调模版的作用,前人的财富对于初学者总是享用不尽的。在制作项目开发进度的Gantt图(甘特图)时,我采用了Microsoft Project,尽管我不很愿意过多地使用Microsoft的产品(这是因为我是SUN和Java的忠实支持者,而非对Microsoft的技术抱有怀疑),然而最后还是选择了它,因为它太好用了,而且还提供了现成的模版,只需要根据实际情况稍作修改就可以了。尽管已经在计划上花去了太多的时间,然而这是值得的。我在制作Gantt图时耗费了一个下午(这还是在有模版的条件下),然而这一个下午我对项目的整个进程有了把握,明确了什么时候该做什么事,每件事的大概持续时间是多少。我惊奇的发现,风险分析已经和即将花去接近两个星期的时间,以至于我都耻于将这个事实记录在内,要知道,代码开发的计划不过是18天而已。这是个不很合适的比例,事实上两至三天的风险分析就已经足够了,对于学生项目而言可以适当放宽,因为还有其他的作业要完成。庆幸地,我发现代码开发的时间正好包含劳动节假期,这是一个不错的巧合。再次强调计划的重要性,这种重要性只有亲身做过才能体会得到。否则,一个无序的开发管理从一开始就泛滥了。没有完善的计划是项目失败的主要原因之一。

我们观察过几个现有的酒店管理系统,有几个是很不错的,各有特点,我们有了明确的方向和赶超的目标,或许它们就是我们潜在的假想对手。有了参照,我们的需求分析和原型搭建可以容易很多。界面相当重要,然而这不是Java的强项,至少不是AWT和Swing的强项,然而我们并不想贸然使用不熟悉的SWT,新技术的风险超过了获得成功的几率。稳妥和做好业务逻辑应当摆在首位,强大完善的功能同样不容忽视。经验告诉我们导师不会太多在意图形界面的细节,所以不必为了一两个像素的差别花去太多的时间,更多地放在提供足够的功能上,这是相当有分量的筹码。

每个人对我们的系统提供哪些功能有很大的分歧,即使对有几种类型的客户端都争论得不可开交,或许应当需求经理说了算,然而这是一个学生项目,每个人必须对自己开发的系统相当熟悉和满意才会充满热情,不得已的,每个人各自做一份功能计划书,下一次例会进行答辩,这是最民主的方式,也可以让每个人充分熟悉这个系统的功能范围。然后,一切才能继续。下次例会之后,一切都将明朗起来。

这是艰难的一周。一切都遭遇极大的阻力,新鲜感过去之后,后遗症出现了。有人出现了厌战情绪,有人时间紧张分不开身,混乱,成为了这一周的代名词。我有着不可推卸的责任。

我们首先试着确定项目的范围,或者说产品的范围,然而诸多的分歧让这个过程几乎停滞。我没有安排所有人很好的做调研,也没有安排所有人认真地去试用几个现有的系统,每个人都揣着自己的想法来到一起,这样也就罢了,更可怕的是很多人根本没有想法就来到了这里,于是对其他人的意见所能做的只有反驳。看来为了造成不必要的争执和尽快达到共识,事前一定要做好充足的准备。我曾经一度以为这个阶段我没有太多的事要过问,因为这是属于需求分析的阶段,我所要做的仅仅是组织开开会而已,现在看来这是完全错误的。这个阶段是最需要沟通和组织的阶段。一方面这是项目开始不久的阶段,大家的凝聚力还没有到可以脱离组织约束就能成事的阶段,另一方面这个阶段特别需要沟通,因为需求分析是后面所有活动的基础。我们的测试经理的一句话让我很有感悟:如果需求分析我不参加怎么知道我该测试什么东西呀。的确,这个阶段如果任何一个人对任何一个环节有任何的不清晰,哪怕是一丁点的模糊,累计到后面很可能带来的是整个项目的崩溃。

我安排了两个人去独立的完成use-case,然而不幸的是他们参考了同一个系统,做出了几乎一样的use-case,这让我始料未及,于是两个人的努力变得没有任何意义,我的初衷是对他们俩的use-case做一个并,现在不可能了。在分配任务前一定要交代清楚,不仅仅是做什么和大概怎么做,还有做的意义都要解释得很明白才行,这样会减少很多无用功。在我们尝试确定具体的功能性需求时,分歧接踵而至。我们对太多的事情不能达成一致,我们做的是酒店管理系统,可我们中的一部分人根本没有住过酒店,另一些人住得较多所以意见和反响很大,我们难以达成一致。更重要的是下周还有考试,这大概是学生项目最头疼的问题,兼顾学业。我们的进度一拖再拖,幸好一次停课的机会让我们重新坐到了一起。是进度表拯救了我,拯救了我们。我展示了进度表,上面清晰地反映出我们已经落后预定进度三天了,要知道项目仅仅开始半个多月。大家有了清醒的认识,不再苛刻追求功能的完美实现,我们砍掉了大部分的次要功能,将他们作为增量的形式发布,尽管谁都清楚这个增量版本等于是天方夜谭罢了。在不至于牺牲太多质量的前提下,我们达成了一致,功能少了很多,然而我们取得了空前的统一,对功能的需求相当清晰了,甚至一些初步实现方案也有了端倪。一切似乎又步入了正轨。对于学生项目,能够完成才是最重要的,重要的是体会这个开发的过程,产品功能是否强大已经显得不重要了。每个人完成任务的能力我也有所了解,这为我以后任务的分配提供了依据。每个人的能力也能从开始的几个任务中得到体现,事实上,这种体现暴露得越早越好。

然而又一个失败让我沮丧,我没有过多斟酌就布置了估算的任务,我安排大家各自分工根据COCOMO和FA(功能点)对活动分解进行估算,然而后来当一个人已经完成提交的时候向我倾诉,FA根本不适合对于某一特定的活动进行估算,它只适合于整个系统。相似地,COCOMO也不很适合于此。我所建议的两个模型竟都不合适做这方面的事情,我只是想当然的以为这是两个万能模型。然而事情必须做,项目计划文档中还等着每个活动的工作量估算去完成,于是硬着头皮只能根据COCOMO大概给出一个PM值了,然后调整一下“杜撰”出一个最终的工作量来。大家做了很多工作,然而却不知晓使用了错误的模型,又是徒劳的努力,这是我个人彻底的失败。在选择模型时,千万不能草草了事,一定要参阅相关书籍,善于使用经典模型是好的,但一定要弄清楚这个模型在这种情况下适不适用。我做了补救,安排三个人对整个系统做一个基于FA的估算,这是比较正式的估算,因为我们已经有了足够的需求分析,这个结果也将是有意义的。然而一些人对估算不以为然,他们认为这是荒唐的事,一方面我们缺乏经验,另一方面未知的事太多,估算显得似乎没有意义。我明白估算出的绝对值是没有多大意义的,至少对学生项目是。然而相对值是有意义的,至少可以知道在哪些方面我们需要更多的人力来完成,哪些事情可以很快解决,这种对比是必要的,对把握进度是极为重要的。

关于评审,我们初步确定的是对一些关键的大型文档(主要是里程碑性的),做DR(正式设计评审),而对于次要文档至少要做一次inspection(审查)。他们的差别是DR需要大量的支持文档和较长时间的讨论,而inspecion可以相对随便。同时,DR不属于同行评审,也就是说这是上级对下级的审查,而inspecion是同行评审,是同事间的沟通和讨论。当然,我们的DR不大可能邀请到上级,也就是我们的导师。我初步想邀请助教参加我们的DR一到两次,这样一方面我们的DR可以比较正式,另一方面可以争取到更多的映像分,要知道这是学生项目中必须面对的现实。当然,每个组员必须一致同意才可以,否则凝聚力会大大下降。一切都只是策划,对于评审我们实在没有任何经验,书本是唯一的知识来源。

考完试之后,需求分析就要随之结束了,正式的设计即将展开,好戏渐渐上演,后面会发生什么,我很期待,也多了一丝担忧。我能做的,就是准备好充足的文档和模版,组织好会议,做好沟通,分布好任务,剩下的,需要每个人的努力。

先说些额外的话,本来想至少每周能记下一些东西的,现在看来真不一定什么时候有空了,工作一定时间积累些东西能形成两三千字就发上来吧,会议记录真的很管用,有时候我都会忘了过去的几天究竟做过什么事情,看看会议记录全想起来了,要不写这个东西就很困难了。今天看到很多朋友留了言,很多朋友的意见很中肯,几句话就让我受益匪浅,在此一并感谢。要重新说明的是,我记录的这些历程本意是想给今后学习软件工程课程的朋友们一些帮助,经验也好,教训也好,前人留给我很多东西,我也希望能做些什么。当然这一定是一个漏洞百出甚至幼稚至极的项目,可能几个月后我回过头来看自己写的东西也会觉得不好意思,不过这一切都是真实的。前辈们阅读之后请多提意见和建议,我很需要你们大家的帮助。如果大家觉得这些文字太可笑了不屑于发表些什么,那很抱歉我耽误了您的时间,但请不要对我个人进行任何形式的人身攻击,谢谢您。

回归正题。

需求分析算是告一段落了。我们的需求经理付出了很多(一些朋友提到用经理一词不很合适,的确,动不动就经理来经理去的似乎我们在做多大的项目一样,也显得不够谦虚。不过仅仅是称呼而已,我给每个人都安排了一个经理的头衔,包括需求经理、评审经理、测试经理等,这样做一方面可以明确各自的主要任务和角色,另一方面大家心理上也会愉悦很多,毕竟,大家都愿意称呼我为项目经理,如果我称呼每个人组员似乎不大合适,有些盛气凌人的感觉,也叫个经理有个缓和,茶余饭后也是大家的一种消遣,缓解一下气氛的笑料,何乐不为呢)。我结合各种模版做出了一份需求规格书(Software Requirements Specification)。我先是参考了Pressman的建议模版(因为我们用的就是Pressman的教科书–<>,<<软件工程,实践者之路第5版>>),另一方面参考了Sommerville的<>,上面给出了需求规格书内容的许多建议,还有就是飞思科技的<>,这本书很特别,基本上就是各种文档的模版,挺有趣的书,给了我很大帮助。当然还有Rational SoDA自带的一些模版,这个很有参考价值,一方面毕竟是大公司的推荐模版,商业性更强,前面的一些模版学术性可能稍强一些;另一方面毕竟是电子版的,可以直接用了,很方便。我基本上就是按照SoDA的模版结合其它的一些稍作修改形成了最终的模版给了需求经理,她的任务就是完成这个模版,因为完成了这个模版也就相当于做完了需求分析,这个模版的内容太丰富了,包括了足够的use-case信息和功能及非功能规约。参考各种模版也是不得已的和必要的,我们没有任何经验,甚至不知道需求文档中需要出现什么,这样用现成的模版很省事,能学到东西,能把事情做好。

Use-case完成得很快,我本以为又会拖很多时间,没想到三天就交工了(包括完成最重的文档),当然我们前期做了很多准备工作,大家基本筹备的差不多了,只是最后画一个图而已。我仔细看过,除了一些Documentation的语法错误以外,没有大的问题,至少我觉得是的。当然,我们准备以此作为一个训练做一次Inspection,长远的是打算针对系统设计文档做一个FTR(以前称呼它为DR,都是正式技术评审的意思,但似乎FTR用得更普遍一些),准备邀请助教参加的,不能出岔子,于是借用这个机会做一个训练,毕竟Inspection和FTR在流程上差别不是很大,区别主要在于参与者的权限,FTR有上级参与(这不是凭空说的,在Daniel Galin的<>中可以找到原话)。

需求文档其实分为两个部分,一个称之为Software Requirements Specification,它包括了几乎所有的内容,除了use-case图,最后我才发现这个问题,use-case图没地方放了,正好Rational SoDA有一个use-case-model survey模版,专门用于形成use-case图的文档,挺适合的,于是出现了这样两份文档,有些奇怪,现在想想可能不大合适,不过也不打算改了。

风险管理拖到现在才最终完成,主要是RMMM的问题,有几个人没弄清RMMM文档的部分内容的含义,有一个内容是风险跟踪,我的理解就是出现了相关风险情况时就加以记录,可是有几个人撰写的时候就在这儿胡乱填了一些东西,挺奇怪的,可能我没有交代清楚。英文的文档就是这个不好,大家沟通起来不方便,这有点违背了文档的本意。记得一本书上说过,如何避免陷入文档驱动的黑洞中呢,很简单,只制作对未来有益和利于沟通的文档,我觉得可以这么说,文档就是用来沟通的。既然英文文档不利于沟通(至少现在感觉上是的),为什么还要采用,呵呵,学生项目嘛,一个直接目的是获取高分,形式上的东西是必要的,尽管可能不很合适。我也不知道今后的工作中是不是一定要用英文文档,英文究竟占据多大的地位也不清楚,先在做些准备不是什么坏事。

现在Chief Architect开始进行设计了,因为我们赶上了预定进度,时间上宽裕了起来。我很相信他的能力,我想作为组长对组员的态度就是用人不疑。我很清楚为什么我会被推选为组长,因为我的设计和编码能力是最强的,我想大多数学生小组选组长都是这个原则。然而现在我不应该去做这件事情,尽管我很乐意,但这是对他能力的怀疑,是对他的不尊重,更何况他也有很强的实力。越权不是一个好主意。当然,我在交付给他设计文档模版时还是给了一些必要的思路和建议,比如按照MVC的要求设计类,比如底层的RMI机制。另一方面,在评审时我可以将我的意见提出来,有很多方式可以让我自己参与到设计中来,当然,前提是第一个版本一定要让该做的人去做,任何事情都一样。这是对制度的遵守,对人的尊重。

不幸或者有幸的,我现在正式成为了第二个小组的组长,这是一个本体采集小组,与现在的酒店管理系统有很大的区别,当然管理上的区别可能不是很大。之所以这样是因为软件工程的教师正是我今后研究生阶段的意向导师,他有意让跟他的四个人单独出来组个小组做个东西,一方面增加交流,另一方面可以尽早接触今后的研究领域。于是有了这个小组的诞生,我还成为了组长。时间分配可能会更紧张,毕竟两个组都不能出岔子,未来的两个月会很忙。同样的,学习的机会也更多了。第二个组的工作我又要重新开始从计划做起了,呵呵,希望自己能好运。

下一阶段的任务,设计,主要就是完成类图了,其他大的方面大家都心中有数了,就差类图了,然后可以开始编码,大约一周之后吧,五一之后完成编码吧,编码怎么分工我还没考虑好,有能力参与的有四个人,GUI只有我比较熟悉,我们拥有一个数据库专家,称之为专家是因为他的数据库编程经验在我们之中是最丰富的,另外的方面我还不清楚,我不很清楚大家在编码方面究竟有多大的能力和潜力,我不想走一步算一步,可能让每个人自己选择负责的部分是一个好主意吧。说实话,需求做得很详细,功能上还是要实现很多东西的,我不时地想起来,总觉得全部实现有困难,导师说过,这是一个允许失败的项目,我可不想失败。我现在能做的就是先去做一个原型系统,把界面大概勾勒一下,让大家心中有数,然后,我们开始。

忘了强调一下Rational SoDA,这是个很棒的文档自动化工具,可以和Rational其他的组件结合得很好,比如根据Rational Rose的use-case diagram可以自动生成相应的文档,很方便,很值得一试。

这一周是忙碌的。

需求分析基本完成了,use-case图几经修改,我们在绘制use-case之前进行过多次的讨论,试图完全明确所有的功能,然后再绘制use-case,企图一次成功,现在回过头看这个想法太天真了。不过经过充分的讨论,第一版的use-case已经基本符合要求了。大概是我们对use-case认识还不是十分明确,做出来的图比较简单,主要体现在各个用例之间似乎没有多大的联系,当然也可能是这个系统本身太简单的缘故。其实在刚做完use-case时,我们都以为这只是应付老师的一个图表罢了,对于项目过程而言没有多大的帮助作用,我仍然记得绘制图表的原则:只绘制对今后有用的图表。然而后面的分析设计中,这个use-case图却真正成为了我们的工作准则。因为这是一个经过充分讨论的成果,得到了所有人的认可,在后面的分析设计中,碰到过一些有争议的地方,一切符合use-case成为了事实的标准,然而这多少成为了一种约束,当然这种约束可能是有益的和必需的。不得不承认的是,这个use-case终究还是有一些遗漏的功能,然而我们后来在分析设计时发现之后,大家都不愿意再修改use-case了,因为相关的文档已经完成,加上时间紧迫,于是只能去掉那些可要可不要的功能,我们的借口就是:要符合use-case。这样做,我们事实上还是在采用瀑布模型,如果按照迭代的方法,这里是应当对需求分析进行修改的。幸好我们没有真正的客户,否则显然不能这么糊过去。自然的,我们失去了一次训练需求变更的机会,有些遗憾。反思为什么会这样:可能可以归结为时间不足,进一步考虑大概是因为进度表制定的不合理,再进一步考虑原因也许在于系统的范围还是定得太大了一点,使得我们的训练广度是保证了,然而精度不够。看来学生项目出于训练的目的,范围应当尽可能的小,甚至是一个HelloWorld都可以接受,因为项目的目的是尽可能熟悉和掌握软件工程的各个环节,软件本身不用很强大,想起一句话:麻雀虽小,五脏俱全。一个小的软件已经足以训练大部分的内容了。

需求文档也完成得很顺利,有了use-case一切都变得简单。对每一个use-case要做一个specification,也就是对它的一些简要说明、这个功能的输入输出、前置后置条件等等,这费了很大的功夫,犯过许多错误。一个典型的:我们需要将一部分信息组织成一个记录写入数据库,这个功能的输出(outputs)以及目的地(destination)是什么:起初的考虑是输出为信息,目的地是记录。然而后来发现这样似乎是有些荒唐的,因为输入也是信息,难道输入和输出不经修改是一样的,那这个功能还做了什么事情。后来改为了输出为记录,目的地为数据库,这是大家比较容易接受的结果,尽管我们也不很确定究竟怎么才算准确。想起以前和老师讨论一些问题时老师的一句话:当碰到两难时,
选择那种符合大多数人习惯,能让大多数人接受的方案。我想这里是适用的。

之后想起来应当做一份glossary(词汇表,或称为数据词典吧),就是对需求分析中用到的一些词加以解释,这些词可能贯穿于整个开发过程中,有这样一份词典后面看文档的人碰到陌生的用语时有据可查。这份文档做得晚了,我就被一件事情困扰过。我们做需求分析的组员对于“续住”这个功能(还记得我们做的是酒店管理系统吗)用的英文单词是continue,这倒无妨,只是我看文档时对着这个单词琢磨了半天也不能参透这个功能的意义,后来和她交流才知道是续住的意思,试想如果当时就有glossary将省多少事。更可怕的,如果我误解了后果将很严重(其实我起初的理解是由登录窗口进入主窗口,叫做continue,呵呵,幸好和她有一个交流)。

这些工作做完之后,我们认为需求分析的文档就基本成形了,于是我们举行了一次评审,这是一次审查(Inspection),由所有组员参与,评审对象就是需求文档。我们提前两天将文档打印分发给每个人回去浏览准备,一个小插曲是打印和复印的费用花去了我们第一笔集资经费(50元)的一半,让我们吃了一惊,后面要勒紧裤腰带省点用了,毕竟大家都还是学生,花的是自己的伙食费。其实我本来以为这次评审将是失败的,因为大家以前没有过经验,而且这段时间大家都比较忙,可能不会太认真的去阅读文档和找出瑕疵。然而事实让我吃了一惊,每个人都做了充分的准备工作,人均花费了两个小时阅读文档,这已经足够了。我们的评审相当顺利,问题接二连三地被提出来。当然有一点遗憾是评审的时间没有把握好,有点拖沓了,不是因为问题太多,而是花了一些时间在如何解决上。按照各种书籍的观点,评审会议应当着重发现问题而不是解决问题,我们不经意的犯了这个错误。然而这样做是有道理的,因为在完成需求文档时,犯的一些错误多半是对这个问题不理解,而不是不知道该怎么解决,也就是说不是很清楚what,一旦明白了what,那么how可能是比较容易的。所以我们有必要及时指出问题是什么,指出问题的本质,这样长远的看是节省时间的,减少返工的次数。为什么大家会愿意去花宝贵的时间阅读文档和找出瑕疵,我想一个直接的原因是因为打印这些文档的开支比较大,大家都很心疼钱,所以不忍浪费,于是才会认真地阅读文档。挺好的。

起初是我们的“首席架构师”完成系统结构的设计,为了节省时间我们试图同时完成系统架构的设计和模块的细节设计,于是碰到了问题,功能上有点不统一,直接原因是对需求没有做很好的回顾和了解,仍然比较模糊,于是,原型系统发挥作用了。我在拿到需求文档之后,花了一个晚上做了一个原型系统,只有简单的界面,示意一下,这大概也是原型系统的初衷之一吧,原型系统本来是为客户服务的,与客户有一个基本的交流对象。我当时的本意是直接做正式的界面(这个天真的想法是很不合适的,然而我当时相当自信,认为没有问题),而不是做原型系统,后来我们的“评审经理”提醒我说你现在做的应当是一个原型系统,用一下就抛弃的,我才察觉到险些犯了一个巨大的错误。庆幸的,这个系统正好可以被用作原型系统,为我们的分析设计做了很好的铺垫。我们的设计师不是很愿意阅读需求文档,更愿意直接看原型系统来发掘设计思路和要求,幸好这个原型是比较完善的,至少没有遗漏一些功能表示。

然而,第一个设计是失败的,原因之一是对RMI(远程方法调用)没有很好的了解,RMI是这个系统的底层实现,这是我的要求,我的另一个要求是力争符合MVC的标准,或者向着它努力,以它为原则。然而我们的设计师之前没有RMI和MVC的基础知识,就直接进行了设计,显然是不合适的。我们否决之后重新阅读了书籍,建立了第二个架构,模块分得也比较仔细和合适了,基本可以接受,然而整个系统结构显得有些冗余和不清晰,问题出在MVC中的M。我们的理解中,V就是界面,对应于分析类中的boundary方面的内容;C毫无疑问就是主控器了;然而M,都知道是模型Model的意思,起初的思路是寻找系统中的名词,找到之后形成类,也就形成了相应的M。于是,系统中充斥着M。去掉一些不必要的,还是有很多,我隐约的觉得有些不必要。我花了一个下午推翻了重做,建立的设计方案中几乎没有M,或者说实体(Entity)类,这样的方案是简单的:界面发出事件请求,相应的控制器进行响应,然后更新界面并反馈信息,没有实体什么事。这或许不是一个面向对象的系统,因为乍一看找不到对象。然而这样的系统实现起来相当简单和直接,难道是设计的倒退吗,还是或者根本没有弄清楚面向对象的实质。我们的设想是,所有的名词(实体对象)都通过数据库持久性存储起来了,访问或者更改的时候直接查库,然后直接把查询结果以ResultSet(结果集)的形式交给界面去更新就可以了,何必假惺惺的封装起来再给界面,然后界面那边又要解封装,似乎多此一举。我们没有找到这样设计的大缺陷,尽管我们知道这可能是不合适的,比如不利于扩展,不利于代码重用等等。另一个重要的缺陷是,界面部分也要完成一些业务逻辑,比如对结果集信息的提取,这显然是不符合MVC要求的。然而鉴于我们现在的编程水平,易于实现是相当重要的。于是,这个方案被接受了,这是一种妥协,更像是一种失败的妥协,或者说这样的设计更像是一种失败的设计。可能后面还会返工,适当的增加一些M的部分,比如至少不能把ResultSet交给界面吧。呵呵,偶尔想起来太荒唐了。

界面设计方面,仍然存在很大的争议,因为可以参考的系统很多,很难达成一致。这部分工作正在做,我把我的初始意见形成草案分发了出去,大家讨论之后试图在五一前达成一致,因为一旦放假,沟通将变得困难。一个合适的考虑是五一期间基本完成编码,当然前提是大家都对各自要做什么相当清楚,接口的定义要一致和清晰,这部分我们还比较弱,设计还是粗粒度的。我们渴望接下来的几天能够提速,现在也正在提速。尽管我们落后进度将近一周,不过通过加快设计并形成良好的设计方案,我们的编码能够节省很多时间,测试也是一样,大家对按时完成充满了信心。当然,没必要也不可能五个人都参与编码,可能直接编码的只有两三个人,我负责界面,另外一个数据库编程的高手,其他的适时而定,编码方面绝对不是人多了时间就短的,绝对不能用人月除以人数得到月份,我觉得对这样的学生系统,一两个人写代码就足够了。

最后用一句话总结这一周:紧张而充满希望。


五一期间一直在写代码,现在看来是个错误的选择。我本以为尽管是一个训练软件工程的项目,然而把程序完成仍然是十分必要的,甚至是最重要的。如果系统都没能按计划完成,那这个项目谈何成功呢。于是,我们决定利用五一期间的长假完成一些代码,主要是我负责的界面部分。为什么从界面开始,因为之前写过一个原型系统,对这个系统的轮廓已经略知一二;另一方面,更重要的是,我们还没有进行详细的设计。设计只是表面的,比如确定了RMI,确定了门面模式,确定了最简单的单控制器机制等等,然而一个核心是内部的方法、属性都没有具体定义,尽管有些可笑的是完成了数据库的初步设计。一切,都有些荒唐,至少顺序上是的,也许是我个人有些急功近利了,想早点完成这个事情,毕竟我们还有别的课要上,软件工程不是我们本学期的全部。当时的想法是:我写写界面,边写边进行类的设计,然后逐渐明确数据库设计方案,然后列出方法簇给负责数据库的拍档去完成内部逻辑。换句话说,所有的接口都是边写界面边确定的。这样做是完全错误的,本以为可以缩短时间,哪知道在我向其他人解释这些接口的时候费尽周折,以至于我自己都很难描述清楚某个方法究竟是做什么用的。这时我才渐渐明白为什么一定要先确立接口,这是大家共同的语言,有了接口,有了明确的子系统划分,大家可以舒适地并行开发。然而现在,我们的情况更像是流水线开发,我做出一个界面,扔几个方法给数据库那边去完成功能。可事实上我在逐渐往后开发时总是不免的又会修改前面的设计,越改越乱,这才造成了数据库那边的编码困难。核心是什么,核心是分析设计不充分,甚至可以追述到需求的不充分。比如确定一个订单,我们只是简单地提到了要有这个订单,然而订单具体包括哪些项目我们没有明确下来,而是打算留到后面的分析设计去完成。我们之所以敢于这样是因为这是一个学生项目,没有真正的客户,我们甚至可以随心所欲地更改需求,只要可以方便我们实现。于是,为了省事,我们将许多稍显麻烦的工作留到了后面,一次一次往后拖,逐渐的,越发混乱。

现在想来,我们应当在需求阶段就明确界面元素(事实上原型系统应当更加完善),这样我们对所有的事情可以达成统一,不至于在后面找实体类时东挑西拣迟迟不能决定。我们的功能或者说范围定义太过模糊,我们没有确定一个明确的问题陈述(导师的推荐项目题中给了一个明确的Statement作为客户的代理,可以据此进行需求分析)。也就是说,我们还不大清楚这个系统到底应当完成什么,然后,一切却开始了。幸好这个项目美其名曰一个迭代的开发过程,我们可以逐步修改我们的需求分析,直到在问题域和我们的能力之间达到平衡,或者说是妥协。其实现在,因为时间关系我们已经放弃了接近1/3的功能,这个数字可能还会继续扩大,最后可能可以真正实现的部分只是一个很小的子集。导师的话提醒了我们:重要的是把整个流程走一遍,真正做出什么东西来并不重要。

我们显然没有追上预定进度,这完全是因为不恰当的提前进入了编码阶段。不过比起导师制定的一些里程碑底线还是绰绰有余的。我们的评审工作得到了肯定,选用经典文档模版收到了称赞。助教提了一些意见,的确,我们在用例分析时犯了些严重的错误:用例,是面向用户的,能够为用户提供有意义结果的动作序列。我们表示了一个用例叫做数据库管理,然后其他所有的用例都include了这个用例,我们为之得意洋洋。然而,我们忽视了这个数据库管理对于用户而言是不可见的,或许它不适合作为单独的用例出现,尽管它的确是有意义的动作序列。在分析阶段将它提取出来建立一个分析包或许是一个合适的选择。同样的,我们在书写需求规约的Action时,写的太过简单,千篇一律。其实Action或许是需求文档中最重要的一个部分,它就代表了这个动作序列,尽可能的详细对于后面的分析设计是极为有利的,可以避免不一致性。

我们几乎跳过了分析阶段,直接进行的设计和编码,对于小的系统,这样做并非不可行,然而带来的不利后果就是可能会产生不少模糊,对一些概念可能会出现不一致,对需求的理解是不详尽的,不充分的。寻找分析包和分析类本身对于理解这个系统是极为有用的,甚至超过产生的制品。寻找分析类是有趣的过程,我们在后面补分析文档的时候体会到了这一点。其实看着一个个包被提取出来相当有成就感,我们对系统的理解逐步深入,各个模型逐渐细化,随之再进行设计编码一定相当轻松。可惜,我们没有忠实执行这个过程,导致我们的设计过程相当艰辛,最终产生了一个“万能类”Controller,处理几乎所有的功能请求。这是很多书上提到的经典反例(特别是三大巨头写的《统一软件开发过程》),很有趣,这个大反例就出现在我们身上。不过这个系统的确相当简单,似乎没有必要将这个控制器再拆减了。即使设计阶段作了拆减,相信我们实现的时候一定会再把它们合起来。

编码真的成为了最没有意思的事情,绘制UML图是那么有趣,编码显得那么枯燥。其实写代码的成就感来源于解决问题的挑战性,一旦完成了设计,就表明所有的功能都是理论上已经实现了的,这样写代码就成了例行公事,哪里还会有成就感而言。尽管对于如期交付是有益的,不过可以想象程序员的生活有多么枯燥和乏味。说到写代码,其实对于这样的小型系统,两三个人负责就可以了,更多的人参与其中,花在交流和协调上的时间远远超过人员增加带来的速度提升。当然,这与我们对接口的定义不清有关,与我们的编码能力和表达描述能力有关,不过对于学生项目,参与编码的人越少越好。事实上,一个小组中,真正有能力编码的又能有几个人呢。

管理方面有一些新的收获,凡是一定要以身作则,比如迟到这件事,起初我要求大家讨论会不能迟到,然而我自己却迟到了几次,说出的话自然没有说服力了。后来自己来得早了,大家自然也相互配合。很多朋友说一个真正的项目经理,应当学会尊重组员,是请求他们做事,而不是要求他们做事。是的,一方面,大家是朋友、同学,不是也绝没有上下级的关系,大家合作的努力完成这个实践,仅此而已。大家更应当学会享受这个过程,能学会些东西更好,重要的是相互熟悉,相互合作,培养这种精神,培养合作的精神,培养这种努力的意志。毕竟,现在学的东西以后能用到的很难说有多少,然而思想上的是能伴随一辈子的,理念和思路值得花时间去研究。

最近的讨论会越来越少,毕竟,进入编码阶段要讨论的事也没有多少,我们更多的讨论仅仅是聚在一起吃吃夜宵,相互交流一下进度,分配一下后面的任务,仅此而已。似乎一切都变得有些轻松,毕竟,大局已定,距离最后的提交已经很近了,大体已经有了定论,需要提交的文档基本已经完成了雏形,评审之后就可以了,我们即将收工。因为对于系统本身的实现不很关注,我们不会将更多的时间花在上面,这意味着后面我们将没有太多的事情可以做。也许一切就要这样结束了。

我们这个周末会有个聚会,算是大家忙了两个月,轻松一下,大家一块儿唱唱歌吃吃饭,调节一下。如果可能的话,为后面几天的编码和测试工作开个好头,大家都能精力充沛的做好收关工作。其实最近的一个月,因为编码的关系,过得并不开心,没有能享受软件工程带来的快感和愉悦,确实,写代码是枯燥的。我们在饶有兴趣进行了一个多月的新事物尝试之后,好奇心淡了,实质的任务多了。前一个月,我们会为了一次评审而欢呼雀跃,那是多么有意思的一件事;现在,我们为了应付助教参与的一次评审而焦头烂额,准备大量的文档已经成为习惯,每天每个人都在和文档打交道。满脑子的英文使得我们已经无暇顾及别的事情,是该好好休息了。都说战线不能拉得太长,两个月对于初涉这个领域的我们而言,是有些长了,有些单调和乏味。我们总是时常后悔将项目的范围定得这么大,然而一切已经于事无补,我们能做的只有在烂摊子上继续走下去,把这件事做做好,问心无愧就可以了,我们不愿意这个实践是被我们“糊”过去的。

不得不提一下人,人的因素对软件工程有多重要已经无需再提,每个人的能力是有差别的,我想组长在安排任务上应当有些考虑。固然大家争取平分所有的任务,然而不是每个人都能够胜任自己的工作,能力强的理所当然可以接受更多的工作。这不是对他的不公平,这不会招致他的反对,这是对他的一种信任,我想每个强手都会乐于接受挑战。组长对于几乎所有的事情都应当有所过问,干预的程度可以不同,但是一定要准确的知道每个人当前在做什么,未来一周要做什么,没有这个度,项目的进度将相当可怕。有时候,订立截止日期是有道理的。一味的放任可能造成进度的拖沓,适当的严厉和所谓“独裁”可以挽救这个项目,然而如何平息大家的不满就需要自己做功课了。


项目结束于20天前,因为忙于考试,没有能及时记下最后几天的工作。这几天又忙着在实验室充电,几乎忘了这个事情。今天看到一个朋友的提醒才想起来应该有一个像样的负责的总结。

项目算是完成了,连夜加工,写程序的只有两个人,我写界面和定接口,另一个写数据库。我们其实已经做好了放弃的准备,因为我们的需求、分析和设计得到了助教的首肯,相当出色,我们心里面也清楚,这个项目得高分是铁板钉钉的了,代码出不出来已经不很重要。另外,我们通过项目得到训练的目的已经达到,不论是UML还是管理方面的一些基本知识我们都有所涉及和了解,应该说能做成这样大家都很满意。至于系统能不能跑起来,只是锦上添花的概念。这样说可能有些可笑,一个没有软件成品的项目怎么能算得上一个成功的项目?然而我们始终谨记这是一个学生项目,我们要的是尽量多涉及一些方面,多体会一些,而不是刻意的只是为了写代码。当然,我们的分析设计还是相当实用的,尽管不是一个非常有艺术的设计,但我们相信一个实用的设计才是最完美的设计。我们的代码写起来还是很快的,只是因为范围定得太大,我们的时间把握不大好,导致大量的功能被删减。尽管如此,复杂的数据库设计仍然让我的搭档费尽心思。确实,我们系统的业务逻辑太复杂了,很难完美的实现。这给我们提了一个醒,在初期定义范围时,一定要考虑仔细,有时候不仅仅只根据功能点和代码行来估算,一定要注意适当的加权,就是所谓3D功能点(也许是这么称呼的,我已经有所遗忘)。比如说即使一个功能可能估计仅需要几十行代码,但是这几十行可能要写一个晚上,我想凡是写过复杂逻辑的朋友们一定都有所体会。所以在确定功能时一定要谨慎,特别是学生项目,功能能少就少,满足基本需要就可以了,这样可以避免分析设计的时间过于拖沓,而且可能是在做无用功,因为后面这些功能会因为时间不足而被删减。更重要的,一定要记住点到为止的思想,我想这个思想应当贯穿项目始终。

话说回来,三个晚上几乎没合眼,我们两个人完成了所有的基本功能。其实我以前做完一些比较大的东西时,都会很兴奋,然而这次没有,相当平静,因为太累了。而且我发现书上提到的一种观点得到了验证:分析设计阶段做得太详细,会导致编码时程序员没有任何发挥的余地而产生不了成就感。的确是这样,我们在编码时仅仅是例行公事一样,没有什么好设计的了,再加上复杂的逻辑搞得大家精疲力尽,没有一点乐趣可言。我想,这是必然的,尽管对程序员显得不公平,可是对这个项目而言是必要的。毕竟,我们总是假设普通程序员的能力在一个团队中是最低的,那么应当由他们来完成最简单的事情——写代码,而且是依葫芦画瓢似的代码。

我不知道其他搭档从这个项目中学到了什么,我想每个人多少都会有所收获。我所看到的,我自己受益匪浅,因为我所进行的活动对我而言都是创造性的——风险、进度、估算……我之前都没有尝试过,所以我会有很多新的想法出来,会有很多新的体验和收获。我们的“架构师”收获也是巨大的,因为诸多的UML图来自于他,我想这种经验的积累是不可多得的;而且分析设计文档也都是他撰写的,这种经验更是让人倾羡的,我想完成一个50页的英文技术文档那种感觉是无与伦比的。我们的“需求分析师”至少在use-case上有所收获,包括use-case specification。可能另两个搭档收获会少一点。负责数据库的也许是最惨的,他付出了最多的劳动,但大多局限于编写代码;而且同样由他负责的测试工作因为时间的关系没有能按照测试计划正式展开,仅仅是按照我们以往的习惯进行的测试,不得不说是一个遗憾。我真的很渴望能多一个月的时间,这样我们的各项工作都会更加完善一些。

一些补充的:风险管理方面成为了最大的鸡肋,因为我们没有时间去维护RMMM;提交文档都用的PDF格式,可能更加正式一些,也更“时髦”一些;很多东西是可以作假的,比如评审工作,即使不进行评审也可以作出像样的文档,但是并不推荐这么做,因为评审实在是一个非常有意思又有意义的体验;尝试相信每个人,因为除了相信别无选择,永远不要怀疑你的搭档的能力,只要你可以恰当的安排工作,他们总能完成得很好,适当的多安排一点是残忍而可行的,除非他们主动拒绝;和气和团结是成功的根本。


最大的收获:项目计划在我看来是学生项目中最重要的一份文档

最大的教训:软件范围的定义一定要小,能小就小,因为你不会所有的时间都用来开发,要注意到超过一半的时间是在写文档、评审、绘图……为什么要这样?为了保证质量

最大的遗憾:测试工作做得不好,没有合理的规划test case,也没有按照规范来测试

最意外的满意:评审工作太有趣了,大家聚在一起讨论感觉很好,而且很有效


我们最后一块儿吃了顿饭,唱唱歌,作为庆祝

我的软件工程最后得分是:96分。原因:我的笔试成绩很不错,同时助教告诉我,我们的项目是最出色的

The End

(原文链接)

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月20日

提高你的J2EE项目的质量
作者: cnJava 发表日期: 2005-11-11 22:31 文章属性:


概述
这篇文章中,Jimmy Jarrett建议开发者,特别是团队领导者,需要作哪些事情来确保他们系统的质量。另外还讨论了一些开源工具,它们在测量系统质量方面能够提供帮助,他还特别强调了责任分明的重要性,缺了它,没有开发团队可以获得成功。
许多人还在错误的认为基于Java/ J2EE技术的系统仍然在代码维护的问题上纠缠,bug的数量,或者功能的欠缺,或者性能的低下。幸运的是,这些问题已经很少与Java/J2EE技术本身相关联了,与它们真正相关的是缺乏一个关注系统质量的过程。为了确保由一个大型的团队或者跨越多团队开发的,一个大规模的Java/J2EE项目的成功,团队领导者必须:
?        使用能够测量质量的工具
?        从这些工具中定义一组质量关卡和一些人为因素
?        分清对提交、监控的责任界限, 加强实施.

这篇文章解释了怎样将这三个策略融入到你的开发战略中,这样才能确保你的团队持续的开发高质量的项目。

工具的重要性

你听说过一个建筑公司试图建造一所房屋,而没有一把高性能的电锯,电钻或者甚至连最基本的象锤子这样的工具都没有?的确,一所房屋也可以没有今天的先进设备而建起来,但是,建筑将会花更长的时间,并且绝对达不到(使用先进工具)相同的水平。你可以用你的手建起一个小茅屋,但是如果你使用了正确的工具,你就可以建起一座大厦。

今天的开发者与那些试图建一所房屋的人几乎一样。对开发者来说工具是最基本的要素,不管是对于提高生产力还是加强质量。开发者使用的工具必须可以让他们在最短的时间内生产出最高质量的代码,这意昧着今天的IDE不再只是用来编写,调试和编译代码的简单工具。对应的,一个IDE必须帮助开发者识别出他们是否遵循合适的编码规范和已知的设计模式,如果他们遵循像Web services这样的工业标准,如果他们的代码追随它的约定,如果它完成每一个需求。别外,如果开发者没有进行持续构建和自动测试的环境,那么一个IDE的能力对加强系统的质量来说就变得更重要了。

进入Eclipse IDE看一下,它提供了内置的功能,当使用插件时,可以同时提高代码和系统的质量。Eclipse是一个开放的,可扩展的IDE,无所不为并不专为什么而设计。Eclipse的Java开发环境是开源的,免费的和完全可订制的。Eclipse通过开源的或商业的订制插件来促进新功能的增加。通过使用Eclipse,特别是图1中显示的一组关键的插件,那么对开发者和团队来说,就有可能对基于J2EE或Java的项目质量进行衡量。

{
ImgLoad(this);
}” border=0 resized=”0″>
图1.Eclipse的插件矩阵图

如果你不能衡量和监控它,控制一个系统的质量是不可能的。理解系统中允许测量的的关键领域非常重要。它们包括系统的可维护性,可靠性和性能。上述明显没有全部包括全部领域,但是这三项作为确保系统质量的基石是非常合适的。

可维护性包括了代码理解或修改的复杂程度,不管它是一个bug修复或是一次升级。良好注释的代码遵守众所周知的编码标准和工业设计标准,它们比那些几乎没有注释的,不遵守开发规范的代码更容易维护。高可维护的代码可以更快地引入更改,这样也就充许业务对新的或变化的需求有更快的响应,最后降低新特性的增加或维护造成的成本。

可靠性表达了一个方法是否遵守它自己的约定,并能够被成功地执行。单元测试可以用来演习一个方法的约定,从而确定代码段的可靠性。单元测试的质量,反过来,也被代码覆盖分析所验证。许多手段可以用来进行测量代码覆盖,包括,但不仅仅是,表达,判断,条件和调用分析。普遍讨论的一个议题是用来确定一个方法的可靠性的覆盖测试的类型和数量。出于这篇文章的目的,简单地说可靠性会随着代码覆盖测试的提高而提高。

系统内方法的可靠性是绝对重要的,因为,扩展来说,它就代表了系统的可靠性。其它问题,如性能或可扩展性,会慢慢出现,它们在扩展单元测试和覆盖分析时可以没有。这样,单元测试和覆盖分析毫元疑问地是保证系统稳定性全部的和最终的解决方案。但是,持续稳定地执行方法的能力代表了系统稳定的好的测量棒。

性能是典型的依靠每个单元所耗时间进行测量的。从一个系统能够处理多少个请求,到网络?吐量,到某个系统调用的响应时间,全部都是依靠单元时间作为测量的标准。更为重要的是要知道,扩展开来说,是系统如何运作的。

为了达到这样的理解,你可能需要测量所有主要的服务方法、或者通过高使用频率,长调用堆栈,或者那些代表了核心构造中最普遍的交易通路来体现的问题域。第一步为性能提供了不一样的舒适度。对大型系统来说,性能应该在开发过程中被持续的维护和监控,以尽早地确定障碍并且避开生产环境下不可预知的错误。

现在,让我们来看一下Eclipse和它的插件是如何帮助开发团队来测量任何基于Java或者J2EE系统的维护性、可靠性、和性能的。

代码生成:可维护性
代码生成是确保一致性和可重复代码质量的最佳方法之一,它不同于基于类型的方式。XDoclet是目前生成Java源代码的工业标准。XDoclet是一个开源的,免费的库,它解析代码,寻找指定的Javadoc标记(元数据),然后用它来生成其它的Java源程序。

XDoclet包含了一组Javadoc标记,它们可以用来生成大多数的的可重复代码,这些代码在主流的基于Java/J2EE的系统中都可以找到,如JavaBean和EJB的home以及remote类,它甚至提供某些专有信息:如Borland Enerprise Server,JBoss, Orion, Resin, Sun Java System Application Server,Weblogic和Websphere。它也支持许多其它技术,如Hibernate, JDO(Java数据对象),和Castor。如果这些还不够,XDoclet还可以扩展,允许开发者创建自己的定制标记来生成自制代码。使用XDoclet,让它为你生成代码,你可以在重复的编码中避免代码错误和bug。

代码度量:可维护性
因为代码容量过大,所以做不到可视地监控整个代码库。不必把每一行都过一遍,度量可确认出存在或潜在的问题。Eclipse的Metrics插件是一个开源的,免费的工具,它可以每一个类,每一个包或者每一个项目级别上生成度量值。为了便于保存历史记录,结果会输出在一个XML文件中。它也包含了一个Ant任务,可以用它来生成上述XML。

Eclipse的Metrics插件提供了超过23种类型的度量。最重要的一些度量包括接口的数量,深度继承树,重载的方法数量,McCabe的三级复杂度,传入藕合,传出藕合和抽象。默认地,Metrics图用蓝色显示合适,用红色显示违规。任何显示红色的部份都代表了一个可能的问题,需要你回头确认。插件有它自己的视图,并在后台运行;这样,它不可以被团队领导者在阶段结束时使用,也可以被开发人员用于自己的代码。

代码覆查:可维护性
代码覆查是一种有效的练习可以用来确保代码质量,也可以用来在编码风格和编码的最佳实践方面指导开发者。Jupiter是一个开源的,免费的工具,可以进行基于团队的代码覆查。Jupiter使用XML文件来跟踪单个的团队成员覆查,覆查使用一个覆查ID和覆查者ID(覆查ID是被团队覆查所共享的)。这些文件被加入到源代码控制中并对其它开发者可用,允许同步的进行多个覆查,并不需要服务端管理。
每个团队成员使用一个XML文件来从源码控制中检入检出,来看一下什么东西需要整理或者其它成员已完成的整理。使用Jupiter可以免除通常在新开发中要严格遵守的bug跟踪制度。Jupiter把队员解放了,他们可以在他们方便的时候进行代码覆查,而不是强迫他们正在解决一个问题时还去参加代码覆查会议。

坚持标准:可维护性
开发标准存在的目的是避免过去的错误重犯。另外,它也确保了代码的一致性和对于将来会维护这些代码的人员的更大的可读性。Eclipse内置了一个遵循Java编码约定的格式化器。虽然这很棒,但一个格式化器对于确保产出高质量的代码是不够的。

Checkstyle建于Eclipse的代码格式化的基础之上,增加了更多的语法检查。它能够指出不合式的代码块,编码错误,重复代码和一些测量违规。更好的是,CheckStyle是完全可定制的,允许用户裁剪检查的类型和组织内部开发标准的严格等级。默认的Checkstyle配置文件是全面的。甚至,我建议开发者投资一点时间在定制这个插件上面,让它完全符合组织的开发需要。定制完成后,Checkstyle的配置文件可以被导出,用到多个项目中。Checkstyle的执行结果是显示为问题视图,它能被过滤和分类。结果可以按文件夹,工作集或者源文件级查看,可以让开发者看到整个编码,子系统或者单个类的质量。

如果你的团队正中进行Web服务的开发,那么WSVT(Web服务验证工具)是一个必须的插件。WSVT可以确认一个Web服务是否符合WS-I(Web服务交互)的基本规范。开发者中需右键点击在一个WSDL(Web服务描述语言)文件上,它就可以对WSDL进行验证,并生成一个可定制的视图报告,来显示出现的冲突。作为额外的好处,WSVT插件监控TCP/IP通讯并且观察、捕捉和验证SOAP消息。WSVT插件因此可以确保接口层和消息层的合规性。

功能测试:可靠性
Eclipse集成了Ant和JUnit。Ant是创建基于Java的应用的实事上的工业标准。JUnit基于Java的生成单元测试的框架。

开发者可以建立在Eclipse中运行的单独的JUnit测试,它为JUnit的运行结果提供了特殊的视图,或者使用Ant的JUnit或JUnitReport任务。JUnitReport Ant任务生成一个可视化的HTML报告,它可以根据定制来代表整个系统的测试或者某一个测试。HTML报告是一种非常好的报表,它可以服务测量项目的质量,可以作为历史记录保存。使用JUnit进行单元测试,开发者必须确定他们的方法符合他们的声明,这样就避免了不规范导致的bug的升级。

代码覆盖:可靠性
当开发者写了单元测试,他们必须了解这些单元测试提供了大程度的代码覆盖。

GroboCodeCoverage是一个开源的工具,它和Ant集成在了一起,通过使用任务来生成覆盖报告。可以生成单个的报告,如行计数报告和方法计数报告,它们分别提供了代码行和方法的覆盖百分比。但是,这个工具的精华是它的摘要覆盖报告。这个报告模仿了Javadoc的结构,提供了一种专业的,高质量的报告,可以作为历史文档保存起来。随着项目的进展,参考这个报告就可以看出在这一过程中代码覆盖是在增加还是减少。通过使用GroboCodeCoverage开发者可以确保他们最关键的代码段被完全的测试过,并发现缺乏覆盖的细小的角落。使用这些信息,他们可以增加或更新现有的JUnit测试,从而提高系统的可靠性。

Profiler:性能
当项目接近完成阶段时,开发者开始更多的思考性能。基于Eclipse的Profiler是一个开源的,免费的监测工具,它针对开发者需要解决的普通的性能问题提供了很多特性。它显示了线程,堆大小,堆dump,方法调用,方法次数,每个包的调用和线程调用树,通过它开发者可以看到时间在调用流中被花费在了哪些地方。基于Eclipse的Profiler帮助开发者了解应用的瓶项在哪里发生,让他们在将产品提交给QA(质量保证)部门或投放生产之前更正错误。

使用工具控制质量的好处
上述所列工具,可以让开发者监控,测量,跟踪和确认需提高的领域。没有这些工具,开发者就会使用他们自己的发明,并且整个团队将会进行自己的代码覆查,这些很显然是很少并且非常因难地对其进行跟踪的。更为重要的是,这些工具不仅能够为开发者使用,也能为团队领导使用。团队领导不再手工地察看代码或者定期地召开代码覆查会议。一个团队领导可以使用这些工具来测量和监控整个的编码,从而在整个开发周期同控制和确认系统的质量。

改变的垫脚石
他们说罗马不是一天内建成的,这同样也适用于为你的基于J2EE或Java的项目实现质量控制。试图从头引入一种处理可能会以失败收场,因为许多人反对改变,开发人员也不例外。一个过程的新方面应该通过时间慢慢地引入,这样才能生根和得到接受。通过逐渐引入质量关卡可以确保这一过和得到接受。
在开发者社区内,关卡也被称作检查站,覆查或质量关卡。抛开语义学不说,一个关卡是开发过程中的一个认识点,包括可交付的某种形式的半成品和对其进行覆查的一组风险承担者。从开发到QA,如不存在QA,那么到生产的过程必须通过关卡来提高代码的质量。项目的历史和它的状态,无论它是刚开始还是正在进行,应该首先说明使用什么样的关卡和工具。

在介绍关卡给开发团队之前,请花点时间确认你的项目需要引入的关卡的顺序。每个项目的需要是不同的,因为它的成员的强项和弱项不同。确认项目可以从中获益最大的质量提高是在哪里,然后应用合适的关卡来认识它们。图2显示了使用Eclipse的插件可以获得的质量提高

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

管理中的十大经典理论


1、彼得原理

每个组织都是由各种不同的职位、等级或阶层的排列所组成,每个人都隶属于其中的某个等级。彼得原理是美国学者劳伦斯·彼得在对组织中人员晋升的相关现象研究后,得出一个结论:在各种组织中,雇员总是趋向于晋升到其不称职的地位。彼得原理有时也被称为向上爬的原理。 这种现象在现实生活中无处不在:一名称职的教授被提升为大学校长后,却无法胜任;一个优秀的运动员被提升为主管体育的官员,而无所作为。 对一个组织而言,一旦相当部分人员被推到其不称职的级别,就会造成组织的人浮于事,效率低下,导致平庸者出人头地,发展停滞。 因此,这就要求改变单纯的根据贡献决定晋升的企业员工晋升机制,不能因某人在某个岗位上干得很出色,就推断此人一定能够胜任更高一级的职务。将一名职工晋升到一个无法很好发挥才能的岗位,不仅不是对本人的奖励,反而使其无法很好发挥才能,也给企业带来损失。

2、酒与污水定律

酒与污水定律是指把一匙酒倒进一桶污水,得到的是一桶污水;如果把一匙污水倒进一桶酒,得到的还是一桶污水。在任何组织里,几乎都存在几个难弄的人物,他们存在的目的似乎就是为了把事情搞糟。最糟糕的是,他们像果箱里的烂苹果,如果不及时处理,它会迅速传染,把果箱里其他苹果也弄烂。 烂苹果的可怕之处,在于它那惊人的破坏力。一个正直能干的人进入一个混乱的部门可能会被吞没,而一个无德无才者能很快将一个高效的部门变成一盘散沙。组织系统往往是脆弱的,是建立在相互理解、妥协和容忍的基础上的,很容易被侵害、被毒化。 破坏者能力非凡的另一个重要原因在于,破坏总比建设容易。一个能工巧匠花费时日精心制作的陶瓷器,一头驴子一秒钟就能毁坏掉。如果一个组织里有这样的一头驴子,即使拥有再多的能工巧匠,也不会有多少像样的工作成果。如果你的组织里有这样的一头驴子,你应该马上把它清除掉,如果你无力这样做,就应该把它拴起来。

3、木桶定律

水桶定律是讲一只水桶能装多少水,这完全取决于它最短的那块木板。这就是说任何一个组织,可能面临的一个共同问题,即构成组织的各个部分往往是优劣不齐的,而劣势部分往往决定整个组织的水平。 水桶定律与酒与污水定律不同,后者讨论的是组织中的破坏力量,最短的木板却是组织中有用的一个部分,只不过比其他部分差一些,你不能把它们当成烂苹果扔掉。强弱只是相对而言的,无法消除,问题在于你容忍这种弱点到什么程度,如果严重到成为阻碍工作的瓶颈,你就不得不有所动作。

4、马太效应

《新约·马太福音》中有这样一个故事:一个国王远行前,交给3个仆人每人一锭银子,吩咐道:你们去做生意,等我回来时,再来见我。国王回来时,第一个仆人说:主人,你交给我的一锭银子,我已赚了10锭。于是,国王奖励他10座城邑。第二个仆人报告:主人,你给我的一锭银子,我已赚了5锭。于是,国王奖励他5座城邑。第三仆人报告说:主人,你给我的1锭银子,我一直包在手帕里,怕丢失,一直没有拿出来。于是,国王命令将第三个仆人的1锭银子赏给第一个仆人,说:凡是少的,就连他所有的,也要夺过来。凡是多的,还要给他,叫他多多益善.这就是马太效应,反应当今社会中存在的一个普遍现象,即赢家通吃. 对企业经营发展而言,马太效应告诉我们,要想在某一个领域保持优势,就必须在此领域迅速做大。当你成为某个领域的领头羊时,即便投资回报率相同,你也能更轻易地获得比弱小的同行更大的收益.而若没有实力迅速在某个领域做大,就要不停地寻找新的发展领域,才能保证获得较好的回报。

5、零和游戏原理

零和游戏是指一项游戏中,游戏者有输有赢,一方所赢正是另一方所输,游戏的总成绩永远为零,零和游戏原理之所以广受关注,主要是因为人们在社会的方方面面都能发现与零和游戏类似的局面,胜利者的光荣后面往往隐藏着失败者的辛酸和苦涩。 20世纪,人类经历两次世界大战、经济高速增长,科技进步、全球一体化以及日益严重的环境污染,零和游戏观念正逐渐被双赢观念所取代。人们开始认识到利已不一定要建立在损人的基础上。通过有效合作皆大欢喜的结局是可能出现的。 但从零和游戏走向双赢,要求各方面要有真诚合作的精神和勇气,在合作中不要小聪明,不要总想占别人的小便宜,要遵守游戏规则,否则双赢的局面就不可能出现,最终吃亏的还是合作者自己。

6、华盛顿合作规律

华盛顿合作规律说的是一个人敷衍了事,两个人互相推诿,三个人则永无成事之日。多少有点类似于我们三个和尚的故事。 人与人的合作,不是人力的简单相加,而是要复杂和微妙得多。在这种合作中,假定每个人的能力都为1,那么,10个人的合作结果有时比10大得多,有时,甚至比1还要小。因为人不是静止物,而更像方向各异的能量,相互推动时,自然事半功倍,相互抵触时,则一事无成。 我们传统的管理理论中,对合作研究得并不多,最直观的反映就是,目前的大多数管理制度和行为都是致力于减少人力的无谓消耗,而非利用组织提高人的效能。换言之,不妨说管理的主要目的不是让每个人做得更好,而是避免内耗过多。

7、手表定理

手表定理是指一个人有一只表时,可以知道现在是几点钟,当他同时拥有两只表时,却无法确定。两只手表并不能告诉一个人更准确的时间,反而会让看表的人失去对准确时间的信心。 手表定理在企业经营管理方面,给我们一种非常直观的启发,就是对同一个人或同一个组织的管理,不能同时采用两种不同的方法,不能同时设置两个不同的目标,甚至每一个人不能由两个人同时指挥,否则将使这个企业或这个人无所适从。 手表定理所指的另一层含义在于,每个人都不能同时选择两种不同的价值观,否则,你的行为将陷于混乱。

8、不值得定律

不值得定律最直观的表述是:不值得做的的事情,就不值得做好。这个定律再简单不过了,重要性却时时被人们忽视遗忘。不值得定律反映人们的一种心理,一个人如果从事的是一份自认为不值得做的事情,往往会保持冷嘲热讽,敷衍了事的态度,不仅成功率低,而且即使成功,也不觉得有多大的成就感。 因此,对个人来说,应在多种可供选择的奋斗目标及价值观中挑选一种,然后为之奋斗。选择你所爱的,爱你所选择的,才可能激发我们的斗志,也可以心安理得。而对一个企业或组织来说,则要很好地分析员工的性格特性,合理分配工作,如让成就欲较强的职工单独或牵头完成具有一定风险和难度的工作,并在其完成时,给予及时的肯定和赞扬;让依附欲较强的职工,更多地参加到某个团体*同工作;让权力欲较强的职工,担任一个与之能力相适应的主管。同时要加强员工对企业目标的认同感,让员工感觉到自己所做的工作是值得的,这样才能激发职工的热情。

9、蘑菇管理

蘑菇管理是许多组织对待初出茅庐者的一种管理方法,初学者被置于阴暗的角落(不受重视的部门,或打杂跑腿的工作),浇上一头大粪(无端的批评、指责、代人受过),任其自生自灭(得不到必要的指导和提携)。相信很多人都有过这样一段蘑菇的经历,这不一定是什么坏事,尤其是当一切刚刚开始的时候,当几天蘑菇,能够消除我们很多不切实际的幻想,让我们更加接近现实,看问题也更加实际。 一个组织,一般对新进的人员都是一视同仁,从起薪到工作都不会有大的差别。无论你是多么优秀的人才,在刚开始的时候,都只能从最简单的事情做起,蘑菇的经历,对于成长中的年轻人来说,就象蚕茧,是羽化前必须经历的一步。所以,如何高效率地走过生命的这一段,从中尽可能汲取经验,成熟起来,并树立良好的值得信赖的个人形象,是每个刚入社会的年轻人必须面对的课题。

10、奥卡姆剃刀定律

1 2世纪,英国奥卡姆的威廉主张唯名论,只承认确实存在的东西,认为那些空洞无物的普遍性概念都是无用的累赘,应当被无情地剃除。他主张如无必要,勿增实体。这就是常说的奥卡姆剃刀。这把剃刀曾使很多人感到威胁,被认为是异端邪说,威廉本人也因此受到迫害。然而,并未损害这把刀的锋利,相反,经过数百年的岁月,奥卡姆剃刀已被历史磨得越来越快,并早已超载原来狭窄的领域,而具有广泛、丰富、深刻的意义。 奥卡姆剃刀定律在企业管理中可进一步演化为简单与复杂定律:把事情变复杂很简单,把事情变简单很复杂。这个定律要求,我们在处理事情时,要把握事情的主要实质,把握主流,解决最根本的问题,尤其要顺应自然,不要把事情人为地复杂化,这样才能把事情处理好。

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年08月26日

分到测试组已经两周了,活一直不太多,翻来复去的测试W001和W016这两个模块,昨天终于结束了W016,今天要把W001结束,然后把这两个模块纳品了。


现在说说测试的一些感受吧,刚分到测试组的时候,连测试式样都不会看,满篇的日文看着头就大 ,组长陈刚很好,感觉他很会带新人,给我们的任务由浅到深,循序渐进,没有一下子把我们当成手来用,可能也是运气,我们组的模块很简单,几乎都是画面的BUG,没有功能上的BUG,我们已用户的角度测就可以咯。


以下是我想的测试流程和一些注意点





































































测 试 基 本 步 骤 项目名 版本 制作日期
KingTour 0.1 2005/8/24
步骤序号 参照文档 步骤说明 错误通知 是否截图 Remark
1 物理設計 参照物理設計中的“画面イメージ”检查Form上各个控件的位置和名称是否都正确    
2 从上到下,从左到右 TAB光标移动顺序是否正确    
3 物理設計 参照物理設計中的“画面項目”和“メッセージ仕様”检查画面中各项目是否都正确校验,以及提示信息是否都正确    
4 単体テスト仕様書 参照単体テスト仕様書中的“単体テスト項目”测试各功能是否都能正确实现    
5 単体テスト仕様書 参照単体テスト仕様書中的“DB値操作確認表”测试数据库中数据是否正确存储    
           







































































控件检查点 工程名 控件名 版本 制作日期
KingTour Form 0.1 2005/8/24
步骤序号 参照文档 检查点 检验规则 错误通知 是否截图 Remark
1 物理設計 参照物理設計中“画面イメージ”检查form名称和图标是否正确 与物理設計中“画面イメージ”一致    
2   TAB光标移动顺序是否正确 顺序为:从上到下,从左到右    
3 物理設計 参照物理設計中“補足説明”的共通处理,检查最小化,最大化,关闭的功能是否正确 物理設計中“補足説明”的共通处理一致    
4 単体テスト仕様書 参照単体テスト仕様書中“単体テスト項目”的画面起動,检查初始值是否都显示正确 与単体テスト仕様書中“単体テスト項目”的画面起動确认方法一致   也可参考物理設計中“UI層処理仕様”的form
5            































































控件检查点 工程名 控件名 版本 制作日期
KingTour TestBox 0.1 2005/8/24
步骤序号 参照文档 检查点 检验规则 错误通知 是否截图 Remark
1 物理設計 参照物理設計中“画面項目”检查输入数据的校验是否正确,注意对输入的位数、IO、必须项、文字属性、初期值的检验,还要特别注意画面项目中备考信息 物理設計中“画面項目”的要求一致   也可参考単体テスト仕様書中“単体テスト項目”的入力チェック
3 物理設計 参照物理設計中“メッセージ仕様”检查错误提示信息是否正确 物理設計中“メッセージ仕様”一致    
4   如果是必须输入项,关掉错误提示信息后,光标是否返回到出错的文本框中,并全选 如果是必须输入项,关掉错误提示后,光标应返回文本框中,并全选    
5            























































控件检查点 工程名 控件名 版本 制作日期
KingTour ComboBox 0.1 2005/8/24
步骤序号 参照文档 检查点 检验规则 错误通知 是否截图 Remark
1 物理設計 参照物理設計中“画面項目”检查此ComboBox的IO是否正确 物理設計中“画面項目”的要求一致   也可参考単体テスト仕様書中“単体テスト項目”的入力チェック
2 物理設計 如果次ComboBox为可写(即IO属性为IO),参照物理設計中“画面項目”检查输入数据的校验是否正确,注意对输入的位数、必须项、文字属性、初期值的检验,还要特别注意画面项目中备考信息 物理設計中“画面項目”的要求一致   也可参考単体テスト仕様書中“単体テスト項目”的入力チェック
3            


























































































































单体测试文档标注规范 项目名 版本 制作日期
KingTour 0.1 2005/8/24
序号 标注时期 标注人 标注内容 标注颜色 Leader审查 Remark
1 UT2测试时 测试人员 所有bug信息 黑色字,茶色填充 测试组Leader 所有截图要在BUG编号上加连接,标注日期
2 返回修改时 制造人员 修改完的bug 黑色字,酸橙色填充 制造组Leader 标注修改日期
3 返回修改时 制造人员 有问题暂时不能解决的bug 黑色字,天蓝色填充 制造组Leader 标注问题原因
4 返回修改时 制造人员 没有修改的bug 黑色字,茶色填充 制造组Leader 不做处理
5 UT2再测试时 测试人员 bug已解决的 黑色字,酸橙色填充 测试组Leader 标注问题已解决,标注确认日期
6 UT2再测试时 测试人员 修改后仍有bug的 黑色字,红色填充 测试组Leader 标注问题依旧,标注确认日期
7 UT2再测试时 测试人员 发现新bug 黑色字,茶色填充 测试组Leader 标注日期
8            
9            
10            
  注:修改与测试在2至7间迭代,直至bug全部解决

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”