有效的开发方式
序言
需求—>分析设计(建模阶段)—>编码实现—>运行时
/ \
/ / \ \
| 第一次迭代 | 第二次迭代 | 第三次迭代 | … | 第N次迭代 | 项目结束
团队:项目经理,需求经理,架构师,美工,编码工程师,测试工程师等
在项目开发的过程中,我们就像一只漫长的行军队伍行走在崇山峻岭中,在翻过的每一个山头后,我们总结来时的路,向往未来的路,然后又毅然向下一个目标挺进。
当我们最终到达目的时,我们在想是否我们选择的路过于崎岖,是不是走了很多冤枉路?而如果我们我们的部队不幸夭折在半路,那么我们的英灵是否也在抱怨,谁在半路夺去我的“美好前程”?
在管理项目时,有ISO9001,有CMMI 4,有质量管理方法(PDCA),有公司的规章制度,那么多的圈把我们套向正确的轨道,可是为什么有时候我们的效率和想法往往没有达到预期的目标了?总结我们的开发方式也许会让我们看清楚,我们到底是在哪做的不够,在哪我们忽略了。
一,我们的开发方式
我先暂时不考虑开发过程中一些细小的过程结点,仅根据需求—>分析设计—>编码实现—>运行时以及以往的经验,总结了我们现在采用的开发方式(或者称为开发模式)。
第一步: 需求:需求和界面原型相互完善
- 主要工作
完成界面的工作以配合需求人员去客户处进行系统讲解。需求设计师完成《需求设计说明书》。
- 需要人员
需求设计师,美工,项目经理。
- 对应完成框架中的部分
- 界面原型的生成。
- 界面权限系统的生成。
- 界面菜单的生成。
- 需完成的文档
《需求设计说明书》、《需求跟踪表》、
- 效果
需求人员可以使用我们制作出的界面与用户进行沟通,并进一步的明确用户的需要。并可以提前去实现与客户的交流。
第二步: 分析设计:根据需求制定计划,同时完成数据库设计(PDM)
- 主要工作
根据需求合理制定工作计划,架构师根据需求完成《概要设计说明书》和数据库设计。
- 需要人员
架构师,项目经理。
- 对应完成框架中的部分
- 估计工作量,合理安排工作时间。
- 开发环境配置:开发语言,开发工具,配置库目录等。
- 数据库表的生成,部分数据库存储过程的生成。
- 需完成的文档
《XXX进度计划.mpp》、《项目估算表》、《项目风险管理表》、《项目估算表》、《 XXX数据库设计.pdm》、《 概要设计说明书》、
- 效果
根据工作量安排好计划,搭建好环境。
第三步: 编码实现:完成界面逻辑和业务逻辑
- 主要工作
通过前面两个步骤,我们已经实现了将除去业务的部分完成。剩下的就是完成基本代码。这部分的工作包括:界面展现逻辑,数据库增删改查和其它业务逻辑(比如删除一个商品的时候要去判断是不是这条商品已经被使用过等这些的业务流程。)
- 对应完成框架中的部分
- 开发界面逻辑和业务逻辑。
- 单元测试。
- 数据库表的生成,数据库存储过程的生成。
- 需完成的文档
《XX模块设计说明》、《readme》、
- 效果
在每次的迭代过程中保证可以跑的程序。
第四步: 运行时:维护升级
- 主要工作
主要是修改测试库中的问题和升级。
- 操作框架中的部分
- 根据测试库中记录的问题进行修改和确认。
- 将一些小型的变更记录到《小型变更跟踪表》。
- 需完成的文档
《用户手册》、《小型变更跟踪表》、
- 效果
最终完成。
二,分析问题,优化开发方式
我们的现在的开发方式先进的地方是采用了迭代开发,能够将变化控制在有效范围内,但这种开发方式也有很多欠考虑的地方:比如在分析设计,编码实现和运行时的分离和弱连接,使得在编码工程师在编码前缺少有效的沟通和计划,在面对变化的能力减弱。
1,分析设计和编码实现的分离,编码前缺少有效的沟通和计划
目前的基本上所有设计都是弱的设计(只是程度不同),就是说设计不能直接的或不能完全直接的产生代码实现,一旦管理不严,代码实现就会脱离设计,尤其在一个项目测试后期或运行期,并且需求变化比较大的时候;甚至一个被长期维护的系统,设计往往早已消失,只有维护的人员知道系统目前的样子。至于从实现反向的产生设计的反向工程,那更是一个高难的动作。这种弱的设计直接导致的就是实现缺乏控制,最后导致软件的失败或缩短软件生命期。目前解决这个问题从技术和人两个角度来考虑,一方面使用UML这样的语言来强化设计,另一方面用CMMI这样的规范来强化人的管理。要指出的是UML对设计的强化是有限度的,CMMI的管理也会大幅度提高成本。
解决方法
在编码开始前,加强开发组长和编码工程师的沟通和交流,使编码工程师有分析问题的能力。在项目管理中,项目经理需要指出项目中高级程序员必须指导他们所属的程序员。(可以使用结对开发的方式)
①.程序员必须了解清楚自己所做部分的需求。
②.程序员必须了解清楚自己与其他人所做模块的衔接点,及其应该注意的地方。
③.程序员在开发前最好编写一个开发的步骤文档
解决步骤
(1) 弄清表间的关系(例如:A表与B表的关系究竟是1:N 还是 1对1 还是 N:M)
(2) 看自己工作所需是视图还是表,如果是视图,先编写好视图的sql语句,这里亦可以当做一个数据备份
(3) 写出业务逻辑运行步骤,例如先计算A,后计算B,再计算C。这样写代码的时候,就可以一步一步根据文档有序的往下编写程序。
(4) 构思出对页面的布局及做法并写进文档。
(5) 让你的上级对文档进行评审以便他对的你的错误地方在编写程序前已可以当面指出。
(6) 编写2点中与他人模块间的衔接点及注意的地方,以及以什么方式衔接(例如是采用接口,还是某个对象)
4.正式编写代码。(为了可以提高自己的写代码的效率,可以利用代码生成器生成基本代码,根据文档增加进所需的逻辑业务。)
5.代码编写完成后,要进行测试。 测试既要自己测试,也要提供大量的模拟数据给测试人员方便进行测试。因此,应该编写一个模拟数据的存储过程。
2,编码实现和运行时的分离,面对变化的能力弱
这种分离导致了开发者在编写代码的需要想象系统运行时的状况,这时候开发者可以用很多实现的方法,使用哪一种取决于开发者的素质和经验,这也就是说编程是艺术的原因。消除这种随意性和不一致,就要通过反复的测试来验证运行时的结果,就是这样也无法保证代码的不作出意料之外的事情。上述因素导致了软件质量低下和漫长的测试周期。解决上述问题,一般是通过提供粒度更大的功能模块, 4GL界面,加强开发规范等方法,流行的XP(极限编程)就是一个比较好的方法,主要也是通过挖掘人的潜能。
我们仔细看:
需求—>分析设计(建模阶段)—>编码实现—>运行时
/ \
/ / \ \
| 第一次迭代 | 第二次迭代 | 第三次迭代 | … | 第N次迭代 | 项目结束
团队:项目经理,需求设计师,架构师,美工,编码工程师,测试工程师等
这个图就像一个松散的链条,一个漫长的行军队伍,问题的复杂度在人为因素的逐级参与下变得更加复杂。
每一次的迭代分离导致从需求到设计到代码实现到产生运行结果,我们想的和我们做出来的往往不一样。于是,为了达到目的:将最终结果约束到最开始的需求上,就需要增加人力成本和技术成本来完成,如购买各种开发辅助工具和增强项目管理和人员的培训,总之是通过增加各类成本来努力消除来软件的质量问题和保证进度。
解决方法:敏捷性开发
在使用敏捷开发前,我们首先思考3个问题:
问题一:
是否在第一次迭代之前就已经确定了第N次迭代的内容?如果是,那么这个内容是粗的还是细的?
问题二:
第N次迭代的结果影响到第N+1次迭代,怎么办?是修改,还忽略掉;
问题三:
第N次迭代过程中发现第N-1次迭代有问题,怎么办?停下本次迭代,去修复第N-1次迭代,还是忽略它,如果忽略它,又在什么时候处理?
如果什么都明确了,那就是增量而非迭代
至于修改还是删除或者停止,这个处理还是要看迭代的结果,以及项目的整体状况
问题一:
可以是也可以不是,如果需求很清楚,是;如果不太清楚,为赶工期边做已经清楚的需求边继续分析需求是可以的。如果是,那么这个内容是粗的还是细的?根据需求清晰的程度决定。一般来说,如果工作做得细,是可以一开始就做细节设计的,特别是各迭代的内容不太相关的情况下。但是要注意,开始做了细节设计具体实施时也往往有变动的。
问题二:
当然要进行修改啊。还没有实施的计划有问题怎么能不修改?这种变动一般来说是必须的
问题三:
一般说来每次迭代结束都必须有严格的测试,大BUG在本次迭代内结束。如果发生你提到的情况,如果BUG严重影响当前开发,当然必须修改;情况不严重且工期紧则可以暂时忽略,留待以后处理。
知道了以上三个问题后,引入敏捷性开发加入到迭代开发中:
对于多变的需求,我们的解决之道是:引入灵活多变的架构(支持七种CRUD开发方式),快速的应对开发。
对于复杂的需求,我们的解决之道是:委派专门的建模专家跟踪理解需求,在需求和需求实现之间搭建桥梁,项目方法上采取多次迭代的敏捷软件开发方式,逐步了解学习掌握需求。
经过我们的优化,我们的开发方式应该变成:
最后用《敏捷软件开发》这本书的一句话总结一下:
个体和交互 胜过 过程和工具
可以工作的软件 胜过 面面俱到的文档
客户合作 胜过 合同谈判
响应变化 胜过 遵循计划
虽然右项也有价值,但是我们认为左项具有更大的价值。