软件构造 第二章 软件构建的过程和工具
第一部分
一、软件的生命周期
1.from zero to one
计划、分析、设计、实现、测试、维护
2.from 1 to n
软件的更新与老化、不同软件之间相互取代演化
二、经典软件模型
两个基础类型:线性、迭代
现有模型:瀑布模型、增量模型、V模型、原型法、螺旋模型
考虑的关键因素:适应变化的能力、开发效率、项目管理复杂性、软件质量
1.瀑布模型:线性模型
按步骤依次实现。利于使用,应对变化代价高
2.增量模型:非迭代
将整个产品分成不同的增量,逐一完成。
以增量的方式实施瀑布模型
3.V模型:线性模型
瀑布模型的扩展,强化测试
强化测试:对代码、文件进行分析
4.原型法:迭代模型
实现系统的原型:原型模拟最终产品的几个方面,甚至完全不同
过程:分析基础要求(细节可忽略)、开发初始模型、评论、修改和增强原型
优点:在项目早期可以获得用户的反馈、用户判断软件是否符合规格说明、对软件进行估算
5.螺旋模型:迭代模型
一种风险驱动的过程模型,每做完一个层面进行评估
三、敏捷开发
1.开发宣言:提倡适应性规划、演化开发、 尽早交付和持续改进,并鼓励对变化作出快速和灵活的响应。
人以及人与人的互动胜于过程和工具
可运行的软件胜于面面俱到的文档
客户合作胜于合同谈判
响应变化生于遵循计划
2.快速迭代
用户参与、短期开发、大量测试、
3.极限编程
原型、持续发布、自动构建、结对编程、测试驱动的开发
四、协同软件开发
开源软件构建模型:没有协同管理控制
细节:
五、软件配置管理(SCM)和版本控制系统(VCS)
SCM的任务是追踪与控制软件中的变化
1)SCM实际任务是版本控制和建立基线
软件配置项是软件配置管理的基本单位,任何需要管理 的要素都时软件配置项(源代码、数据、文档、软硬件、环境等)
基线 是在某时间点上,通过评审和认可后的版本,作为后续变化的基点。
2)分支和进化图(属于SCI或一个系统)
在分支上进行并行开发,如测试新功能
其他人员不想在新功能完成之前涉及新功能
分支对单个开发人员也很有用
通过正确的设置,任何程序员都可以 从任何位置拉出或推送到任何位置,从而在合作模式中创造出极大的灵 活性。
版本控制系统(VCS)
Local VCS 本地管理
Centralized VCS 集中式管理,通过云端交互
Distributed VCS(eg:git)分布式管理,用户直接交互或通过云端交互
版本控制术语:
▪存储库:我们项目中版本的本地或远程存储
▪工作副本:我们可以处理的项目的本地可编辑副本
▪文件:我们项目中的单个文件
▪版本或修订版:内容的记录我们在某个时间点的项目
▪改变或差异:两个版本之间的差异
▪头部:当前版本
版本控制系统的功能
▪可靠:只要我们需要,就可以保留版本; 允许备份
▪多个文件:跟踪项目的版本,而不是单个文件
▪有意义的版本:变化是什么,为什么要制作?
▪还原:全部或部分还原旧版本
▪比较版本
▪查看历史记录:整个项目或单个文件
▪不仅仅是代码:散文,图片,...
允许多个人一起工作
六、git
1)git存储库
.git目录:存储所有版本、控制数据
缓存区:内存中
工作目录:本地文件系统
2)文件的三种状态
修改:工作目录中的文件与git存储库中的文件不同,但不在临时区域中
分阶段:文件已修改并已添加到暂存区
提交:该文件在工作目录和git目录中保持相同
3)Git中的对象图:
Git上的所有操作都是在一个图数据库上进行
从另一台机器/服务器复制git项目意味着复制 整个对象图。
对象图中的代码:不重复保存个版本中没有发生变化的文件、每个文件的每个版本只保存依次,多个提交可共享版本
4)分支:分支是在版本控制下对对象的复制,以便修 改可以沿两个分支平行进行
第二部分
一、软件构造的一般过程
1.编程
1)开发语言:c++,python,java等等
IDE:集成开发环境:方便编写代码和管理文件;能够编译、构建;结构清晰;有GUI界面;支持第三方扩展工具
2)建模语言:建模语言是一种人工语言,用于表达信息、知识或系统,以一套一致的 规则定义来可视化、推理、验证和交流系统的设计。
3)配置语言
配置程序的参数和初始设置
应用应提供工具支持配置文件的维护
某些计算机程序只能在启动时读取其配置文件
其他人定期检查配置文件的变化
2.静态代码分析:在没有实际执行程序的情况下执行的计算机软件分析
1)代码评审:
正式代码评审:一种结构化的检查 代码和文档缺陷的过程
轻量代码评审:电子邮件、结对编程、工具辅助
2)该过程提供了对代码结构的理解,并有助于确保代码符合行业标准、自动化工具可以帮助程序员和开发人员进行静态分析。
3.动态代码分析:运行程序以分析代码
程序需要经过充分的测试
利用测试度量技术(如覆盖率)确保 代码的可能功能均被充分测试到
用来测量 程序的时空复杂度,特定指令或函数的调用频率或持续时间
4.调试与测试
测试为软件的利益相关者提供有关被测产品或服务 质量的信息
1)测试:程序能否正常运行,能否满足所有需求
技巧:联想V字模型、测试需求文档
2)调试:
调试是识别错误的根本原因并对其进行纠正的过程
调试往往是成功测试的后续环节,成功测试不意味着没有发现错误, 反而相反
测试和调试不会提升软 件质量,而是发现缺陷的主要手段
软件质量应通过认真的分析需求、良好 的设计、高质量的编码来确保。
调试是最后的手段
5.重构
重构是在不改变代码外部行为的前提下,改善其内部结 构。
(1)投入短期时间/工作成本,对系统的整体质量进行长期投资
(2)保留语义使代码更易维护和修改、进行单元测试以证明代码正常工作
二、狭义软件构造过程:
1.构建系统:
编译代码、打包和测试解释型语言、编译和打包web应用程序、执行单元测试、进行静态分析得到bug报告、输入不同格式的输入文件,得到人可读的文档
2.编译语言
编译后得到目标文件, 后续被链接入类库或者可执行程序中
最终得到可部署到目标机器的发布包
版本控制工具。
源树和对象树:特定开发人员使用的源文件和编译对象文件集。
编译工具:输入文件并生成输出文件的工具(例如,将源代码文件转换为目标代码和可执行程序)。编译工具的常见示例包括C或Java编译器,但它们还包括文档和单元测试发电机。
构建机器:执行编译工具的计算设备。
发布打包和目标机器:打包软件,分发给最终用户,然后安装到目标机器上的方法。
·基于Web的应用程序的编译和打包。
- 使用静态HTML页面
- 使用Java或C# 编写的源代码
- 使用JSP,ASP或PHP语法编写的混合文件以及多种类型的配置文件
2.构建系统的组件:
1)源树:程序的源代码被存储为多个磁盘文件,将这些文件安排到不同的地方称为源树,其结构通常反映了软件的体系结构。
2)对象树:一个单独的树层次结构,用于存储由构建过程构建的任何对象文件或可执行程序。
3)编译工具:将可读的源文件转换为机器可读的可执行程序文件的程序。
编译器:源文件 -> 对象文件
链接器:多个相关的目标文件 -> 可执行的程序映像
基于UML的代码生成器:模型 -> 源代码文件
文件生成器:脚本 -> 文件
4)包装类型:
档案文件:zip和解压缩
软件包管理工具:UNIX风格,例如.rpm和.deb
定制的GUI安装工具:Windows风格
3.构建过程和构建描述
构建过程:构建工具调用每个编译工具来完成工作,这是一个端到端的事件序列。
构建描述:构建工具需要构建描述信息,基于文本的格式编写
构建系统如何被使用:
开发人员构建:开发人员已检出VCS的源代码并正在专用工作区中构建软件,结果发布包将用于开发人员的私人开发。
发布版本:为测试组提供一个完整的软件包供验证,软件的质量足够高时为客户提供相同的软件包。用于发布版本的源代码树只编译一次,永不修改。
健全性构建:与发布版本类似,但并非针对客户,可以每天发生多次,并且趋向于完全自动化。
4.java编译工具
(1)Java开发工具包(JDK)
(2)GNU Java编译器
(3)Eclipse Java编译器(ECJ)
java中打开文件:与机器无关的字节代码,用于描述程序流,而不是直接编译为本 地机器代码
java的可执行程序:Java 语言是动态进行类的加载,在运行时根据需要,类会被加载入内存。
java程序要求两点:必须为JVM提供包含main方法的类的名称。 这用作执行的起点。 - 还必须为JVM提供类路径,该路径用于标识其他类的位置。
java中的库:.由于动态加载的特性,可以随 时替换和升级JAR文件(需要确保兼容性)。
5.子目标和构建变体
构建方法:可以存在任意数量的构建方式,每个方式都使用稍微 修改的构建过程并创建一个稍微不同的发布包
1)三种不同的构建方法:
构建子目标:仅重建开发人员正在处理的树的部分。
构建不同版本的软件:定制输出以改变软件的行为。
构建不同的目标体系结构:为各种不同的CPU类型和操作系统编译相同的源文件集,包括x86,MIPS和PowerPC等CPU以及Linux,Windows和Mac OS X等操作系统。
2)构建子目标
任何大型软件都可以分成许多子组件,通常采用静态或动态库的形式。
避免耗费时间,最好限制构建子组件的数量。
6. 构建工具:Make、Ant、Maven、Gradle、Eclipse