软件构造过程与配置管理
一、软件开发周期(SDLC)
从无到有,再从有到好
二、传统软件过程模型
两个基本模型:线性过程、迭代过程
已经存在的模型:瀑布过程、增量过程、V字模型、原型过程、螺旋模型
选择合适模型的依据:
(1)用户参与程度有多大?–适应变化的能力
(2)开发效率/管理复杂度
(3)开发出的软件的质量
1、瀑布过程
特点:
•线性推进
•阶段划分清楚
•整体推进
•无迭代
•管理简单
•无法适应需求增加/变化
2、增量过程
特点:
•线性推进
•增量式(多个瀑布的串行)
•无迭代
•比较容易适应需求的增加
3、V-Model
V-model表示一个可以被认为是瀑布模型的扩展的开发过程。在编码阶段结束后,流程步骤向上弯曲,形成典型的V形,而不是以线性方式向下移动。
4、原型设计过程(迭代)
迭代:开发出来之后由用户试用/评审,发现问题反馈给开发者,开发者修改原有的实现,继续交给用户评审。循环往复这个过程,直到用户满意为止。时间代价高,但开发质量也高。
在原型上持续不断的迭代来发现用户变化的需求
5、螺旋过程(迭代)
非常复杂的过程:
•多轮迭代基本遵循瀑布模式
•每轮迭代有明确的目标,遵循“原型”过程,进行严格的风险分析,方可进入下一轮迭代。
三、敏捷开发
敏捷开发:通过快速迭代和小规模的持续改进,以快速适应变化。
敏捷开发 = 增量 + 迭代(每次迭代处理一个小规模增量)
• 极限的用户参与
• 极限的小步骤迭代
• 极限的确认/验证
四、软件配置管理和版本控制系统
1、软件配置管理
软件配置管理:追踪和控制软件的变化
软件配置项:软件中发生变化的基本单元(例如:文件)。软件的任何组成部分(源代码、数据、文档、硬件、各种环境)都可能随着软件生命周期的时间而更新。
基线:软件持续变化过程中的“稳定时刻”(例如:对外发布的版本)
CMDB:配置管理数据库(存储软件的各配置项随时间发生变化的信息+基线)
2、版本控制
版本:为软件的任一特定时刻(Moment)的形态指派一个唯一的编号,作为“身份标识
古老的版本控制方法:通过复制文件并修改文件名
为什么需要版本控制?
对个人来说:
(1)回滚到上一个版本
(2)比较两个版本的差异
(3)备份软件版本历史
(4)获取备份
(5)合并相同早期版本的分支版本
对团队来说:
(1)在多个开发者之间共享和协作
(2)记录每个开发者的动作,便于“审计”
版本控制的术语:
仓库:项目中版本的本地或远程存储
工作拷贝:在开发者本地机器上的一份项目拷贝
文件:一个独立的配置项
版本:在某个特定时间点的所有文件的共同状态
变化:即code churn,两个版本之间的差异
HEAD:程序员正在其上工作的版本
版本控制系统:
本地版本控制系统:仓库存储于开发者本地机器无法共享和协作)
集中式版本控制系统:仓库存储于独立的服务器,支持多开发者之间的协作。
分布式版本控制系统:仓库存储于独立的服务器+每个开发者的本地机器
五、Git(软件配置管理工具的一个例子)
1、管理软件演进过程中的变更
git diff HEAD:查看 workspace 和 local repository 的差别。(HEAD 指向的是 local repository 中最新提交的版本)
git diff:查看 workspace(工作区) 与 index(暂存区) 的差别。
2、Git 仓库
Git仓库有三个部分:
(1)本地的CMDB
(2)工作目录:本地文件系统
(3)暂存区:隔离工作目录和Git仓库
仓库中每个文件属于以下三个状态之一:已修改、已暂存、已提交
Git的Object Graph存储在存储库的. git目录中。
从另一台机器/服务器复制一个git项目意味着复制整个Object Graph。
–复制命令:git clone URL local_repository
Object Graph:版本之间的演化关系图,一条边A->B表征了“在版本B的基础上作出变化,形成了版本A”
Object Graph,作为Git项目的历史,是一个有向无环图(DAG)。
commits是Object Graph中的点。commit的情况可能有:每个commit指向一个父亲、多个commit指向同一个父亲(分支)、一个commit指向两个父亲(合并)
分支只是一个指向commit的名称。
HEAD指向当前commit。
在Git中,与之前commit中相比未发生变化的文件,无需重复存储
传统的版本控制系统:
在Git中(Git存储发生变化的文件(而非代码行),不变化的文件不重复存储):
一个典型的Object Graph(文件未发生变化,则后续多个版本始终指向同一个文件;文件发生变化了,存储两份不同的文件,两个版本指向不同的文件):
Git是支持分支和合并的。
在Git中创造分支和合并分支的流程:
Git也支持协作:
3、Github
基本流程:commit, branch and merge
协作流程: fork and pull request
六、软件构造的一般流程
1、编程
语言:
从用途上划分: 编程语言、 建模语言(e.g., UML) 、配置语言(e.g., XML) 、构建语言(e.g., XML)
从形态上划分:基于语言学的构造语言、基于数学的形式化构造语言、基于图形的可视化构造语言
(1)编程语言:
编程工具:集成开发环境(IDE)
一个IDE一般包括:源代码编辑器、智能代码补全工具、代码重构工具、文件管理、 库管理、软件逻辑实体可视化、图形化用户界面构造器、编译器、解释器、自动化build工具、版本控制系统、外部的第三方工具
(2)建模语言:
建模语言是一种人工语言,可以用来表示由一组一致的规则定义的结构中的信息、知识或系统,其目的是可视化、推理、验证和交流系统的设计。
(3)配置语言:
配置语言可以在运行时改变软件的行为,分离稳定和不稳定的部分
2、代码评审和静态代码分析
正式的代码审查,比如Fagan检查,涉及一个有多个参与者和多个阶段的仔细、详细的过程。
轻量级代码检查通常需要比正式代码检查更少的开销,但是如果执行得当,它同样有效。
静态代码分析是在没有实际执行程序的情况下对计算机软件进行的分析(对正在执行的程序进行的分析称为动态分析)。该流程提供了对代码结构的理解,并有助于确保代码遵循行业标准。
3、动态代码分析
动态分析:要执行程序并观察现象、收集数据、分析不足。对代码的运行时状态和性能进行度量,发现代码中的潜在问题
4 、调试和测试
测试:发现程序是否有错误
调试:定位错误、发现错误根源。调试是最后的手段。
5、重构
重构:在不改变功能的前提下优化代码