![一个完整的软件研发流程是怎样的?](http://img.jingyanzongjie.com/240919/0T50C913-0.jpg)
说到软件研发流程,一些同学可能看不起这种标准化流程,会觉得不管三七二十一,立即上手编码才是王道,需求可以等到后面再明确,设计则是完全不需要的步骤,否则感觉速度太慢 , 他们管这叫互联网软件开发精神 。什么是互联网软件开发精神?开源共享、模块化编程、极客精神 , 而不是野蛮开发 。
【一个完整的软件研发流程是怎样的?】
我在读《聊聊架构》这本书时写过一篇读后感,感叹终于出了一本可以让我看很久的架构书,而不是 1、2 小时就能看完的所谓 ** 牛逼架构宝典 。我们经常遇到这样的面试者,你请他画总体架构图,他估计连听都没听过 , 你换一个提问的方式,问他采用了哪些框架 , 他立马和你说 SSH、Spark、Mesos,一大堆,但当你让他画出架构图时,他会很茫然 。当然,你更不用期望他思考诸如为什么 Hadoop 的 MapReduce 并行计算模型会采用 Pull(拉)模式介于 Map 和 Reduce 之间,而不是采用 Push(推)模式?为什么会有 Spark 出现等等此类问题了 。这些问题我会在后续文章讨论,这里只是想说 , 其实这些框架的产生,都是源于研发流程中的架构设计环节发现了问题 , 并逐渐积累的解决方案 。
以基线产品开发过程为例
一般情况下,企业开发软件时会按照基线和定制两块并行方式执行项目开发工作 。无论什么公司,都需要遵从一套成熟的产品研发过程体系,才能做出质量较好的产品 。因此,如果出现项目较多的情况,应该合理地安排基线和定制之前的里程碑,让基线产品能够尽量多地收集用户的通用型需求,为定制项目进度实现技术支撑,减少定制项目中大量更改代码、需要新增模块情况发生 。此外,产品研发过程体系也需要按照业务实际时间要求变化,不要拘泥于一定要按照瀑布方式,或是敏捷方式进行管理,凡事都需要找到契合自己的方式 。鞋合不合脚,只有脚知道 。
我们这里以一个基线产品开发过程作为流程解释基?。?需要注意的是,以下说描述的各个阶段,在项目执行前要明确各个阶段的目标、指定计划、及时沟通,并确保各个时期所有成员对项目理解一致 。
项目启动会
项目启动会的目标是明确该产品开发项目的目标 。目标不是孤立存在的,目标与计划相辅相成,目标指导计划,计划的有效性影响着目标的达成 。所以在执行目标的时候,考虑清楚自己的行动计划,怎么做才能更有效地完成目标,是每个人都要详情清楚的问题 , 否则,目标越是不清晰或是过高,都会影响项目的实际结果 。
项目启动会需要说明项目目标、阶段划分、组织结构、管理流程等关键事项,并将这些内容写入 PPT(最好是有固定格式和范文 , 让团队内部或者公司内部共同遵守规范),需要大家达成一致 。对于关键角色任命 , 事前也需要听取相关领导和项目主要干系人的意见 。
用户需求
软件开始开发前需要确定代价和所获得价值的对比 , 也就是 ROI(Return On investment),一旦确定需要创建,就需要安排一系列的资源来支撑这个软件的生存 。这是需求的最原始描述 。
为什么既要有用户需求,也要有产品需求?因为两者是有差异的,用户需求由用户提出,对技术一般不描述,只描述产品目标 。产品需求是根据用户需求转化而来的技术实现需求,需要针对用户提出的产品目标进行细分 , 总结出具体的每一个功能点,再针对每一个功能点细分为各种不同的操作流程,对每一个操作流程进行技术化定义 。
用户需求和产品需求容易发生不一样 , 这是因为虽然大家都在谈需求 , 但是出发点可能不同 , 造成了双方关注点和思维方式不同 。用户需求关注的是系统如何支持业务流程 , 背后的需求是“实现业务目标” 。技术人员关注的是合理技术方案,背后的需求是“工作量”、“实现难度”和“系统性能” 。
产品需求
我们需要弄清楚产品经理或项目需求提出者为什么要做这个项目?这是最本质的业务需求 。需求分析确定的业务需求 , 都是从业务需求推导出来的,都必须为业务需求服务 。
产品需求一般包括产品需求规格说明书和产品需求矩阵 。产品需求矩阵一般按照子系统、功能集、执行单元的结构列出所有的功能需求,每列则对应每项功能的工作步骤以及每个步骤的工作量 。
产品需求写完后,需要进行评审 。在需求评审会上,产品、技术详细评审需求是否完整,产品功能的正常场景是什么?是否形成闭环?异常场景是什么?是否考虑周全?
需求评审后,开发和测试负责人,分别编写技术方案和测试用例 。技术方案评审,开发负责人拉上涉及到其他系统的负责人一起讨论,技术方案中必须要有业务流程图和时序图,业务流程图是为了梳理开发对业务的理解,是否和需求一致 。时序图是了梳理本次需求涉及的系统交互 。技术方案评审通过后,确认工作量和交付时间,反馈给产品 。
总体设计
设计阶段的目标主要是对待开发系统的构架进行分析和设计,并建立系统构架的基线 , 以便为之后的实施工作提供一个稳定的基础 。
设计阶段包括了系统架构的输出,一个好的系统架构设计可以帮助人类梳理业务逻辑且抓住核心需求,设计稳定可扩展的业务系统,评估业务开发周期和开发成本,有效的规避风险 。例如盖房子的时候得有建筑图纸,有了图纸,才能核算施工周期 。
总体设计是整个系统的框架型设计,意义及其重大,一般情况下不能省略(只有维护项目可以省略总体设计,因为基准项目已经设计完毕),所有的产品开发项目均需要首先进行总体设计,它是设计首要步骤,决不允许本末倒置,不能出现先编码后设计的情况,这是软件开发的第二大痛点(第一大是需求不明确、任意变更需求) 。
总体设计分为三个阶段:
第一阶段:初始设计 。在对给定的数据流图进行复审和精化的基础上,将其转化为初始的模块结构图 。
第二阶段:精化设计 。依据模块“高内聚低耦合”的原则,精化初始的模块结构图,并设计其中的全局数据结构和每一模块的接口 。
第三阶段:设计复审阶段 , 对前两个阶段得到的高层软件结构进行复审,必要时还可能需要对软件结构做一些精化工作 。
概要设计
概要设计的目的是描述系统的每个模块的内部设计,对总体设计和详细设计承担承上启下的作用 。
概要设计按照结构化设计方法进行设计 。结构化设计方法的基本思路是:按照问题域,将软件逐级细化,分解为不必再分解的的模块,每个模块完成一定的功能,为一个或多个父模块服务(即接受调用),也接受一个或多个子模块的服务(即调用子模块) 。模块的概念,和编程语言中的子程序或函数是对应的 。
概要设计阶段把软件按照一定的原则分解为模块层次,赋予每个模块一定的任务 , 并确定模块间调用关系和接口 。
在这个阶段,设计者会大致考虑并照顾模块的内部实现 , 但不过多纠缠于此 。主要集中于划分模块、分配任务、定义调用关系 。模块间的接口与传参在这个阶段要制定得十分细致明确 , 需要编写严谨的数据字典,避免后续设计产生不解或误解 。概要设计一般不是一次就能做到位 , 而是反复地进行结构调整 。典型的调整是合并功能重复的模块 , 或者进一步分解出可以复用的模块 。在概要设计阶段,应最大限度地提取可以重用的模块,建立合理的结构体系,节省后续环节的工作量 。
概要设计文档最重要的部分是分层数据流图、结构图、数据字典以及相应的文字说明等 。以概要设计文档为依据,各个模块的详细设计就可以并行展开了 。
详细设计
详细设计阶段就是依据概要设计阶段的分解,设计每个模块内的算法、流程,为每个模块完成的功能进行具体的描述 , 要把功能描述转变为精确的、结构化的过程描述 。
详细设计这个阶段,各个模块可以分给不同的人去并行设计 。设计者的工作对象是一个模块,根据概要设计赋予的局部任务和对外接口 , 设计并表达出模块的算法、流程、状态转换等内容 。这里要注意,如果发现有结构调整(如分解出子模块等)的必要,必须返回到概要设计阶段,将调整反应到概要设计文档中,而不 能就地解决 , 不打招呼 。详细设计文档最重要的部分是模块的流程图、状态图、局部变量及相应的文字说明等 。一个模块对应一篇详细设计文档 。
概要设计阶段通常得到软件结构图 , 详细设计阶段常用的描述方式有:流程图、N-S 图、PAD 图、伪代码等 。而详细设计的目的是描述某一个模块内部的处理流程、开发方法和编码技巧 。一般来说,详细设计由项目简介、模块说明(具体说明每一个模块内部的流程、功能、逻辑、消耗以及未解决问题)、接口设计(包括内部接口和外部接口)、数据结构设计(包括物理结构和逻辑结构)、特殊处理等几个部分构成 。软件的详细设计,最终是将软件系统的各个部分的具体设计方法、逻辑、功能采用文字方式进行表述 。这样在实现过程中 , 编码人员原则上严格按此进行代码实现即可 。