软件过程框架实践
目 录
1 前言
1.1 背景
软件工程已经有了40多年的发展历史,但是它仍然没有成为一种成熟的学科。敏捷、CMMI、RUP,各种软件开发方法层出不穷,潮来潮去,让一线开发人员无所适从。产业界实践与学术界研究分歧严重。。。也许这本身就不应该成为一门学科。
近年来,软件的理论界和实践者在软件开发过程的定义、度量、改进方面做了大量的研究,提出了大量的过程模型、度量方法、度量标准、改进策略,但现有的大部分方法过于宏观、抽象、复杂,作为战斗在第一线的实践工作人员,如何做到理论联系实际,执行一套行之有效的简单、实用、科学的过程模型,直接帮助开发者定义、评价、改进过程, 提高开发者的软件研发能力,这些是本文所探讨的问题。
1.2 从实践中来到实践中去
本文力求从实践中来到实践中去,自觉抵制三话(假话、大话、空话)之类的行为与思考模式。在这里,软件工程管理上的灵感都应该来自于第一线的实践工作,欢迎读者提供更多的实践经验来丰富本文内容,共同打造出一套行之有效的软件过程框架。
1.3 开发辅助工具选型策略
本文对于开发辅助工具的选型上,以适用、实用为前提。我们在软件过程当中应该关注如何做到有效的管理,而不应该迷信工具,如“夸父追日”般年复一年地追索,认为工具能解决现实中所有的问题,似乎用了什么什么就能提高管理水平,这是不切实际的奢望,因为管理水平将最终从具体个体的水平体现出来,就比如不会玩游戏的人给他再好的装备都死得一样快。其实很多实用的工具就在身边,问题是如何选择、利用它们来武装自己,简单、实用、能解决具体问题就行。任何工具都仅仅是作为管理的一种辅助手段,必须有机的结合起来,才能达到目的。
1.4 迭代开发模式策略
迭代开发是OOA/D成为最佳实践的核心,敏捷实践是有效地应用UML关键。
相对于 “瀑布”生命周期,迭代和进化式开发对部分系统及早地引入了编程和测试,并重复这一循环。这种方法通常会在还没有详细定义所有需求的情况下假设开发开始,同时使用反馈来明确和改进演化中的规则说明。
在迭代开发中,我们依赖于短时快速的开发步骤、信息反馈及针对反馈信息的改写来不断明确需求和设计。相比之下,瀑布模型提倡在编程之前就预先完成需求和设计步骤,而这往往在现实项目当中是不切实际的奢求。研究表明,瀑布模型与软件项目高失败率具有极大的关系,而迭代方法与较高的成功率、生产率和低缺陷率具有关系。
迭代开发是以小步快进的方式,根据用户和测试反馈信息(测试驱动)不断层叠推进,才能得以保障在有限的开发周期内完成项目。对于用户和测试反馈不及时、对于反馈不及时处理或者无故吃掉等行为,都是项目管理的大忌,必须避免。
1.5 快速发布与迭代策略
需求在开发过程当中发生改变是不可避免的,用户通常在工程开始的时候并不能确定他们想要的是什么。当我们采取快速发布策略时,可将工程变动提至较早的时间段,这是保证迭代开发成功的基础,否则就和瀑布模型没啥两样。瀑布模型最大的恐怖在于需求变更在上线前大爆发,这一般是因为直到上线前一刻,用户才体验到你的系统到底和他所想象的有多大区别,而在此之前用户和开发者基本处于两个语境当中。
对于每个项目来说,我们将以往项目现成的主程序和主界面作为基线,复用他们,即刻部署一个框架性的应用系统,发布的初版可能仅仅是登陆界面、带系统管理模块(用户、权限、角色、片区管理等已组件化的通用模块)的主界面。
在项目开发过程当中,一旦需要新增模块,就可以在主界面上添加相对应的菜单并做权限配置等:具体方法见《常规_窗体类_MainForm.pdf》。如此,在开发过程当中,可即刻部署到内部测试环境或者用户体验环境中,使得用户可以及时发现问题à及时提出问题à及时迭代。形成一个良性的信息反馈链。最终,当正式提交用户的时候,将会是个无缝过渡的上线过程,或者至少不至于出现颠覆性的需求变更。
1.6 快速开发框架策略
RAD技术需要相对应的工具和开发平台相配套,否则就是空谈。
一个成熟的RAD开发平台,应该具备:
l 基于.NET框架、逻辑五层、适用于internet/intranet、完全面向对象的技术架构;
l 针对当前流行的关系型数据库(Oracle & SQLServer)通用的、透明的持久层中间件,使用者可基本无需编写持久层代码;
l 提供工具和模板,辅助开发者快速、标准、自动地生成业务层代码,同时,实体映射部分代码根据数据字典也自动生成;
l 封装通用的、透明的逻辑层之间的调用接口,开发者仅需按照面向对象的设计方法编写和使用业务类即可;
l 封装通用的业务规则及其校验机制,并提供统一的业务规则注入方式;
l 提供用户、角色、权限管理的基础方法,封装权限规则及其校验机制;
l 提供通用的UI组件,封装数据处理的界面逻辑、业务规则校验、权限校验等;
l 结合IDE工具,使用者可在设计器上通过参数配置、鼠标拖拉,自动生成80%的界面代码(单业务类操作界面可达到100%);
l 基于事件驱动、跨物理域、跨逻辑层的消息总线技术(EDA);
l 跨物理域的技术实现由框架完成,对于研发人员无需关心物理分层所带来的技术问题(2层、3层物理架构、通讯协议可一键切换),而通过为实施人员提供的配置工具,来具体实现应用系统的物理部署;
1.7 文档编写策略
文档的本质是什么?为什么要写文档?什么样的文档才是有用的文档?
文档的本质就是“记录”,而记录的方法却有多种多样,“我们没必要用文字成篇的去描述,而一两个图形或者图像更有表现力”,UML如是说。
大多数的开发人员没有主动写文档的习惯,我们有没有想过大家为什么不喜欢写文档?这,因为并不是所有的文档都有用,大概九成以上的文档是实际上的多余,特别是详细设计文档,特别是在当今分析、设计形式多样化的现实下。
我们编写详细设计文档的目的是什么?不就是让自己或者后继者(包括维护人员)能够理解你的代码吗?那么,只要能达到此目的就可以了,至于形式么,何必拘泥于八股文、大部头的文档?类图、注释、流程图、序列图。。。这些和代码段相关的单元级别的文档要能一一对应、在物理位置上要越贴近,就越容易方便被维护,这样的文档的生命力就越强。
l 只有为开发人员(包括维护人员)所利用的文档才是有用的文档。
l 只有能及时被维护和更新的文档才是活着的文档。
那么,开发过程中哪些信息需要记录?我们不可能什么都记录,要知道,写文档需要时间,阅读理解这些文档更需要时间。
在开发过程当中,存在两种行为,一种是有章可循地按照某种开发模式、开发方案进行开发,还有一种是本项目特有的、新的算法、新的架构。对于前者,我们可以通过技术框架、业务框架进行提炼,以技术文档的形式教会开发人员使用,那么只要开发人员按照这些模式和方案进行开发,产出的代码基本就是可控、可维护的,我们不必在这些代码段上花费太多精力去写文档,最多注释一下使用到了哪个开发模式或开发方案就可以了。剩下的时间,我们就可以专注于第二种行为,如何记录下这些行为的内容?首先必须依靠面向对象分析和设计来框定这些行为,因为“面向对象”是目前最贴近人的思维模式的开发方法,而类似存储过程等过程化的代码,与机器较为贴近,要让人理解,出现长篇累牍的文档是必然的,而且是必须的。这样,使用面向对象分析和设计,产出UML就是理所当然的行为,我们知道其可读性和可逆性是业界公认的。
2 需求分析
需求分析包括需求调研和分析建模两个步骤。
需求调研一般是为分析建模框定系统边界和范围,为商务合同的敲定提供谈判的依据。
分析建模是对调研内容的丰富和细化。在迭代开发模式下,分析建模在时间周期上会与设计开发发生重叠,为每一步的开发迭代提供设计依据和测试依据。
需求分析的重要性毋庸置疑,在一个项目中,所有代码、文档的源头就是需求文档,需求文档的质量决定了整个项目的命运。
2.1 不可缺失的内容
l 细化到原子级别的功能点
l 无二义性的业务规约条件
l 对象-关系模型ßà类关系图ßà数据建模(ER图)
l 对象-行为模型ßà状态图、协作图、活动图
2.2 工具
l PowerDesigner
l Microsoft Office Visio
2.3 产出
《系统需求调研报告.doc》
《系统需求分析报告.doc》
2.4 规范
《规范_数据库与框架协调设计方法.pdf》
2.5 迭代
正如上文所述,需求在开发过程当中必然会发生变更。所以,需求分析也将是个迭代过程,每次迭代都必须对分析报告的版本进行升级,并根据其变更内容制定二次迭代计划。
当然,所谓的迭代是在商务合同所圈定的系统边界范围内进行的,否则就得请客户部门重新对新的需求增补所带来的工作量进行协商谈判了。
3 软件项目计划
对时间和工作量进行评估是一门艺术。一个项目管理者所应该具备的特质是“在未来还是一团迷雾的时候,就有勇气进行估算”。
估算一个项目软件开发过程中的资源、成本及进度,需要常年积累的经验、需要了解以前的有用信息,以及当存在定性的数据时进行定量测量的勇气。
3.1 资源估算
对于.NET技术下进行的开发设计,以下数据仅供参考:
模块类型 | 难易程度 | 每功能点设计资源(人天) | 每功能点编码资源(人天) | 系数 |
基础信息 | 单表 | --- | 0.05 | --- |
多表关联 | --- | 0.2 | *表单数 | |
业务模块逻辑层 | 按接口数计 | --- | 0.1à0.2 | *接口数*表单数 |
按规约数计 | 0.2à1 | --- | *规约数 | |
业务模块界面层 | 按数据源数计 | --- | 0.05à0.2 | *数据源数 |
按窗体数计 | 0.1à0.5 | 0.1à0.5 | *窗体数 |
上述人天,是按照熟手标准进行统计的,如果对模块做总体估算的话,一个中等模块大致需要2à3个人天。对于新手来说,也许要乘上2à10的系数,然后随着项目进展递减,这取决于新手在以往工作经验和灵性等综合素质。
提请注意的一点是,当一个项目组团队成员均是来自五湖四海的状况下,此时工作量的评估是要冒很大风险的。
3.2 工具
l Microsoft Office Project
l Microsoft Visual Studio
3.3 计划制定
l 制定总体规划,确立里程碑
l 根据业务需求进行自上而下的分解
l 任务分解到工程,与解决方案的工程保持一一对应关系
l 注意优先级、工作顺序(串行、并行)
l 安排资源,任务周期的确定需要征得开发人员的认可
3.4 任务分解方法
l 根据业务需求,划分子系统à构建解决方案
l 根据子系统的数据模型,划分Business模块à在解决方案上构建Business工程
l 根据子系统的业务规约,划分Rule模块à在解决方案上构建Rule工程
l 根据子系统的业务功能点(用例),划分Windows模块à在解决方案上构建Windows工程
3.5 计划跟踪与调整
l 每周至少2次以上的跟踪,检查任务完成情况
l 根据计划进展情况,调整资源调配、时间进度
l 根据测试及用户体验反馈信息,制定迭代计划
3.6 规范
《规范_命名空间与工程划分.pdf》
4 面向对象设计
4.1 工具
l Microsoft Office Visio
l Microsoft Visual Studio
4.2 产出
《概念设计说明书.doc》
《逻辑设计说明书.doc》
4.3 规范
《规范_界面风格.pdf》
业界公认之面向对象分析准则
5 面向对象编程
5.1 工具
l Microsoft Visual Studio
l CodeSmith
5.2 产出
工程代码和注释
5.3 规范
《程序员编码规范(.Net).doc》
《规范_类名命名规则.pdf》
《规范_视图存储过程命名规则与存放方式.pdf》
业界公认之面向对象编程准则
技术框架、业务框架之相关设计方法和设计方案
6 面向对象测试
6.1 产出
测试用例
测试报告
6.2 步骤策略
l 模型测试
l 单元测试
l 集成测试
l 有效性和系统测试
7 缺陷跟踪、维护阶段
维护阶段集中于“改变”,与以下几种情况相关:
l 纠正错误;
l 随着软件环境的演化,而要求的适应性修改;
l 由于用户需求的变化而带来的增强性修改。
维护阶段重复定义和开发阶段的步骤,都是在已有软件的基础上发生的。
7.1 工具
l TFS
7.2 规范
维护过程当中的文档可以由工具进行记录,但是与工程相对应的开发文档必须进行同步的版本升级。原则上代码和文档在系统版本升级的同时一并升级,而当项目周期紧资源不够的情况下,可考虑事后补写文档,但这个工作必须安排计划完成。
8 配置管理
软件配置管理主要是对软件生存期过程中的各种阶段产品和最终产品演化和变更的管理,它是软件质量管理的重要组成部分。CMMI中对于软件配置管理具有明确的关键过程域和关键实践约束。
配置管理在软件过程当中,最大的收益者应该是开发人员,如果配置管理得当,可以成为开发人员的得力助手。比如,在编码过程中无需切换窗体即可方便地检索到与代码对应的设计文档,这也使得代码和文档进行即时的版本同步成为无障碍的一件工作;又比如,可以大大地避免同步开发所带来的对代码管理上的冲突和混乱。
8.1 工具
l VSS/TFS
l Microsoft Visual Studio
8.2 规范
《规范_VSS版本签入签出方法和规范.pdf》
《规范_设计文档及存放方式.pdf》
9 质量跟踪
上述所讨论的一切,如果没有一一对应的Checking,那我们干脆就不做得了,这还能节省更多劳力更多时间。。。当然,这是短期行为,只是把隐藏的问题拖延到将来爆发而已,时间长了会一团糟。
9.1 需求分析质量跟踪
l 通过后续工作中出现问题来验证;
l 通过迭代过程中用户反馈来验证;
我们项目经理往往兼职需求分析工作,但大家要明确一点,在一个团队里大家是平等的,需求、设计、编程,只是分工不同而已,不是上下层的关系,而是软件工厂流水线上前后工序的关系,做后道工序的人有权对上道工序的质量说三道四,有错必改、具备开放的心态,是我们项目组每个成员最基本的工作态度。
但是人往往是有弱点的,最好的解决方法是,让需求分析工作交给专职分析师去做,项目经理可以把这部分精力投入到质量跟踪工作中去,因为这部分工作往往被我们忽略了。
9.2 项目计划质量跟踪
项目管理委员会进行评审和跟踪。这点我们已经在执行着。
9.3 面向对象设计、编码质量跟踪
l 通过迭代过程中的测试过程来验证;
l 通过迭代过程中用户的反馈来验证;
上述这些工作,只能保证我们交付的系统是满足用户需求的,但并不能保证内部的代码有没有符合规范和要求,包括代码的可复用程度,而这决定了项目的可维护性。但对于项目组来说,没有人会关心这点的。
上述这些工作,如果交给专职人员会不会更好?
首先,测试工作完全可以与开发工作并行,而要让开发人员去做测试的话,势必人为地延长了项目周期,这是项目组最担心的事情;另外,开发人员和测试人员的成本是不一样的,让开发人员去做测试,得不偿失,这是公司最厌恶的事情。
综合上述问题,我们应该组建专职的QA团队,工作职责如下:
9.3.1 测试任务
l 根据需求分析文档编写测试用例;
l 根据测试用例进行测试工作;
l 根据测试结果提交测试报告;
l 根据测试报告的反馈信息(bug已排除等)迭代测试任务;
9.3.2 规范执行度检查
l 抽查设计文档、代码文档、测试文档,提交整改报告;
l 抽查配置管理状况,提交整改报告;
9.3.3 面向对象复用度检查
l 编写、宣传已产品化的技术组件、业务组件、设计方案;
l 检查技术组件、业务组件、设计方案在项目中的落实情况,并提交整改报告;
l 研究各个项目中所用到的算法、业务场景,提炼出可复用设计方案、产品化的组件;
最后一项工作是个长期持续不断的工作,虽不能立竿见影,但日久将大大改观我们的开发团队素质。我们知道,对于软件公司来说其根本是具备一支有战斗力的团体,否则很多事情将会心有余而力不足。
本工作目前已在一定范围内执行,整理出了如下内容并不断在扩充当中: