1.前言
应用软件系统是事件驱动的软件系统,系统通过接口接受事件后,交由系统业务层处理,业务层处理完事件后将需要的信息存入数据库,整个应用软件系统分为三个子系统:接口子系统,业务子系统,数据库子系统,业务子系统进一步分为三个子系统:表示层,业务层,数据接入层。
其中业务层是整个系统的核心,表示层负责通过接口子系统接收系统事件交给业务层处理,数据接入层供业务层使用完成数据的持久化。每个层对编程人员的技术要求是不同的,表示层需要了解的技术根据接口子系统选择的不同而不同:如windows界面,需要对MFC有比较深入的了解,web界面则要求对asp,asp.net,或jsp有比较深入的了解。数据访问层需要的技术则由数据库子系统的选择决定,另外还需要了解:ODBC,JDBC等。
接口子系统的选择:windows界面,java界面,web界面,命令行接口,CTI, API等
数据库子系统的选择:关系数据库,普通文件等
基于以上对应用软件系统的理解,软件开发流程的输入是用户的业务需求,输出就是系统的业务层、表示层、数据接入层的代码,以及接口和数据库,以及各种文档。
2.需求分析阶段
需求分析阶段的常见问题是:需求分析不够深入,对问题域没有仔细研究,急于进入设计阶段。造成这种问题一方面是因为项目赶进度,另外很大的原因是很多人不知道如何进一步深入研究问题域。需求分析阶段不仅要列出系统的use case,更重要的是要列出use case的输入输出和例外情况等,以及问题域中的对象之间的静态关系和动态关系,如对象间的包含关系,继承关系,调用关系等。
需求分析阶段另外一个常见的问题是常常将需求分析等同于数据库设计,需求分析阶段定义的是系统作什么,而不是怎么做,需求分析的结果应该与具体的技术实现无关。数据库设计是技术实现的细节,应该尽可能的推迟技术细节的决策,不应该使技术细节束缚了我们对系统需求的理解。需求分析阶段应该从用户的角度对系统建模,不应将大量的技术细节暴露给用户,导致系统易用性差。
需求分析阶段可以进一步细分为业务需求分析阶段和系统功能需求分析阶段。在很多研发性质的系统中,不注重业务需求分析,只有系统功能需求分析,导致开发人员知其然不知其所以然。
系统功能规范文档与业务需求文档的重要区别有以下几点:
- 内容不同:系统需求分为功能需求和非功能需求,功能需求进一步分为业务功能需求和非业务功能需求。系统需求规范文档除了包括业务需求文档中的业务功能需求,功能规范文档需要增加以下内容:系统的非业务功能需求,由于业务需求由计算机系统实现而产生的功能需求,如系统需要系统管理员管理,系统管理员的角度产生一些非业务功能需求,另外需要描述系统非功能需求:数据量,性能要求,响应速度,可用性要求,可靠性要求,界面语言要求等等。
- 阅读的对象不同:业务需求文档是用来与业务人员交流,功能规范文档是开发人员开发的依据
- 使用的语言不同:业务需求文档使用自然语言书写,而功能规范文档使用比较严谨的语言,如:uml书写
- 对编写人的要求不一样:业务需求编写人员只需要对业务系统熟悉,系统规范由系统架构师完成
体现系统架构师价值的地方是编写系统规范文档和业务层设计, 系统规范文档是下一步界面设计,业务层设计和数据库设计的依据,表示层,业务层,数据访问层之间是相互联系的,它们之间的关系应该在系统规范文档中找到。
3.架构设计阶段
架构设计阶段的常见问题是将架构设计理解为技术架构设计,实际上架构设计分为技术架构设计和业务架构设计。技术架构一般由系统软件商提供,可以在不同的应用软件系统中使用,例如:微软的MFC, SUN的J2EE等。对于一个应用软件系统,更重要的是业务架构的设计,也就是将需求分析阶段中得到的各种关系,根据系统的非功能需求将需求分析转变为代码。
其实没有业务架构的设计也是可以的,很多项目中直接将对象之间的各种关系以数据库的方式实现,这样的系统不是面向对象的,因此面向对象设计的很多好处不能体现。由于在架构设计阶段中没有进一步细分,通常会导致不能准确估计任务量,造成项目计划变成摆设。
4.详细设计阶段
详细设计阶段一个重要的任务是系统持久化设计。对应用系统而言,持久化设计只是管理存储的机制,有多种技术手段可以选择:可以是面向对象数据库管理系统,简单的文件,或者是关系数据库,也可以是使用ORM工具等。总之应该把它留到最后作为细节处理。我们不应该将我们的系统和任何特定的技术绑定在一起。我们可以根据需求自由选择需要的持久化技术,并且保留在将来需要时更改持久化技术的自由。
5.编码阶段
编码阶段还处于小农经济,自给自足,没有分工合作。
编码阶段以use case为粒度安排工作,这样的安排方式要求每一个开发人员必须对表示层,业务层,数据接入层的所有技术都要有比较深入的了解,由于每个开发人员各自只对自己的use case负责,对别人的use case不了解,但是每一个use case会有功能重复的地方,导致大量的重复工作。
编码阶段工作安排的粒度应该是类,编码阶段工作的安排原则是先分层,再分割,按照表示层,业务层,数据访问层分开后,每一层内可以进一步分为不同类,使用测试驱动的编程方法,每个编程人员单独编写代码,并进行单元测试。每个层次的编程人员只需要对某一种技术有比较深入的了解。
6.测试阶段
很多人分不清什么是单元测试,什么是集成测试,什么是系统测试?测试的顺序是先单元测试,然后是集成测试,最后是系统测试。单元测试是源代码级的测试,一般由编程人员自己使用各种unit工具测试,是白盒测试。集成测试是在单元测试结束后,将一个或若干个单元作为一个子系统的黑盒测试,测试子系统内的所有组件可以正确的交互,集成测试通过对子系统不断增加新的单元最后完成整个系统的测试,集成测试不应由开发人员完成。
最后引用一句我非常赞同的关于软件开发的一句话作为本文的结束:过渡信赖工具和过程以及低估智力和经验都是软件开发灾难的源泉。