论高效、高质量软件开发
2008 年 4 月到 2010 年 3 月我们开发了曼图林业管理信息系统,我是项目经理负责需求调研、设计和系统核心开发,我将以这套系统论述如何进行高效和高质量的软件开发。
曼图林业系统解决的业务问题:曼图林业总公司包括多个省公司和分公司,它们分布在不同省县,曼图林业主要业务包括:收购、采伐、销售、营林。曼图林业想通过这套系统解决以下问题: 1 、原来分散在各地的业务数据难以汇总和分析,而且这些业务数据存档也不完整; 2 、解决业务数据计算量大而且计算复杂。解决这些问题的意义在于: 1 、减轻业务执行人员工作量,例如前后关联业务数据可以自动导入,计算过程可以由系统自动处理; 2 、对于管理者,可以保证及时准确得到原始业务数据,从这些业务数据中可以分析出业务执行情况,业务收入情况,甚至道收益情况,能够得到林木资产等等对管理决策至关重要的信息。
曼图林业信息系统得业务范围包括:采伐、销售、林班蓄积资产、仓库林木资产、计划(由于收购已经结束、营林刚刚开始,所以这两个业务就不在一期范围)。下面大概介绍这几个业务
计划:计划中首先选定采伐林班,然后估算可以采伐多少木材,然后估算采伐费用和其他税费,最后估算销售价格,这样就可以得到销售收入,然后和收购成本比较就知道是赚钱还是赔钱,从而决定是否采伐,如果采伐就做一个采伐计划表。
采伐:采伐可以分成两个过程,首先分析采伐收益:实际调查林班可以采伐多少木材,然后收集实际销售价格、实际发生各项费用和收购成本计算收益状况,决定是否采伐,如果采伐进入到下个环节:向政府申请采伐,得到政府批复、采伐许可证、定采伐合同、采伐入库登记、采伐结算、林班蓄积分摊和林班采伐工资分摊
销售:销售环节包括多种销售方式,由销售合同、销售出库、销售结算、林班收入分摊组成
系统自动计算和处理所有分摊和计算,而且保证前后关联业务数据有效性,和前后管理业务数据自动导入。
系统开发首先我们要面对的问题就是:我对林业业务一点不懂,连基本常识都不了解。客户公司配合我们做系统得是财务部门,他们特点是业务全面,但对业务细节有不熟悉的地方(他们业务人员都在分公司或者林场),另外我们在上海,他们财务在南昌,也做不到经常见面。所以要求我做到积极应对需求变化。
整个系统我们采用框架和技术如下:后端 spring+struts+hibernate 和 java 、数据库采用 mysql 、前端 ext2.1 和 javascript 。使用框架可以节省我们处理相关技术细节的精力。
根据我的经验和这个项目实际情况我把这个项目开发分成三个大阶段: 1 、需求说明阶段、 2 、设计开发阶段、 3 、修改完善阶段。
从 2008 年 5 月到 2008 年 7 月底我撰写完需求说明书并且通过需求评审,这个阶段的意义在于,确定系统范围,这个范围将来也不能变化,熟悉组织架构和理清业务流程,确定模块,而且不应有较多变化,确定模块主要功能和模块数据字典。这个过程对业务规则没有提取出来,是一个缺陷。在我写需求文档同时安排了一组开发静态模型,一组熟悉 ext 技术
从 2008 年 8 月开始进入开发到 2009 年 3 月结束,这个阶段完成了 70% 的模块基本功能开发,这个阶段是至关重要和决定成败的阶段,我采用了如下技术和方法。
一、分层:前端页面,以 ext 框架和 javascript 技术开发,数据库层以 mysql ,应用服务器层分成实体层、业务层、 action 层、持久层。实体层包含业务方法,业务层包沟通实体层和持久化层的桥梁, action 起到后端和前端沟通的桥梁,持久化层实现数据持久化和现实。单独分出一个业务层首先解决单独实体层不能解决业务问题,其次把业务从 action 分离可以让代码更容易复用。
二、抽象和继承:首先从持久化层分析,虽然有很多模块但是他们都对数据库进行相同操作,例如:增加、修改等,只是操作的数据表不同,对应得 java 实体类不同而已,所以通过抽取一个公共处理类,让每个模块的持久层都继承它,如果有不同处理要求可以通过覆盖或者模板模式达到满足个性处理要求。这样可以减少大量处理代码,可以加速开发进度,减少错误发生的可能,从而提高质量。
业务层也存在类似抽象要求,但要比持久层更个性化,所以职能使用模板方法,譬如处理销售结算和采伐结算,我设计了一组抽象接口和实现类,在他们之中实现算法框架和公共处理方法,这样可以减少代码编写、测试量,肯定提高质量。但是有个缺点就是增加了抽象类,导致类之间调用关系更多,对于维护代码的人技术要求更高。
Action 同样存在这样的抽象,但是它只有基于下面的编辑框架之上,如果没有下面提到的编辑框架, action 层就不能被抽象
三、编辑框架:作为管理信息系统至少 50% 代码都是围绕信息的编辑产生的。所以要减少代码量,首先必须制造一个平台来处理这些操作。而我在 vb 、 delphi 这些环境有开发这样平台的经验。这里要解决的第一个问题就是与类型相关问题,例如客户类、供应商类,我通过反射技术和 newinstance 技术达到处理代码和类型无关;第二个问题就是不同类型模块,例如单表模块和主明细表模块,他们处理还是有很多差别的,我通过桥梁模式,抽象类对应不同类型模块,实现类对应不同实现。第三个问题就是同一类型模块的相同处理方法,可能还有个性化处理,使用模板方法解决这个矛盾。从最后效果看,代码减少很多,这样对提高质量和加快进度起到很好作用。
四、职责分配:这里主要指业务层的职责分配,如果分配不好系统的灵活性就不复存在,如果有流程、算法等变化所有相关代码都要重写,进行合理分配可以复用基本的功能(系统变化多数是变化控制部分)。职责分配表现在,不同构件之间分配和构件内部分配(在第一点分层中已经说了构件内部分配),分配的原则是谁掌握信息谁就处理。下面决个例子说明职责分配,例如采伐结算,入库构件知道某单合同共入库多少材积,而采伐合同知道木材价格,所以让入库构件统计数量,并填写到结算单上,让合同构件把价格填写到结算单上,然后结算进行计算。
五、页面开发:用户 web 页面以 ext 框架为基础,以 javascript 脚本语言开发,根据以往经验,肯定也要开发一个前端页面框架。我首先学习同事做好的一个模块,掌握 ext 的一些基本特性,然后逐步开发出几类编辑框架,这里不存在数据类型问题,但存在不同类型模块类型问题,也要解决相同处理的个性要求。页面框架没有使用继承技术,如果使用了可能框架更优美,另外弹出选择控件,下拉控件等几个控件是同事做的。
大概到 2008 年 10 月上面五项工作基本完成,然后我们就进入模块开发阶段(在模块开发过程中还进行上面工作的完善)模块开发过程中我做了三类模块,演示如何调用前面开发的构件和代码,其他所有模块是同事开发的。
大概是 2009 年 3 月完成除结算、分摊类模块开发,这以后就进入到开发的第三个阶段,修改完善阶段。
2009 年 3 、 4 月老板让我们通过视频进行系统交流,由于存在以下问题,我们的系统不成熟运行起来不是很顺畅,另外他们对我们系统也不了解,这种沟通方式简直无法进行,所以进展很小,我只能按照我对系统的理解把结算和分摊模块做完。接下来几个月客户没有时间陪我们修改系统,一直到 2009 年 10 月下旬才去南昌,进行面对面沟通。
2009 年 10 月、 11 月、 12 月我共去南昌三次,这三次主要修改三方面内容,系统易用性,例如哪些字段要显示,操作方式;另外就是业务单据处理方式,例如结算可以分次进行,采伐设计中样地信息变化等
2010 年 1 、 3 月我和客户确认这套系统满足 2008 年 4 月需求调研是对系统得定义,也就是确认由财务部门主导的系统开发工作结束,并拿到客户验收报告。