0-1 课程简介
课程目标:
1.认识软件构造的质量标准与目标,学习软件 构造的基本过程
2.初步掌握面向关键质量目标(可理解性、可维护性、可复用性、健壮性、时空性能)的软件构造基本技术
3.多种不同的软件构造方案,有什么差异?
4.如何在需求不同的情况下选择最合适的软件构造方案?
5.能力转变:
程序设计与实现能力 :功能->质量
系统设计与实现能力 :具体->抽象
系统分析与评价能力 :编程->工程
利用现代软件构造工具的能力 :手工->工具
软件设计的循环过程:
1.确定需求
2.写代码
3.测试代码发现代码缺点
4.debug发现缺点的起因
5.修改掉缺点
6.循环1-5
软件设计的优良习惯:
1.未雨绸缪
2.考虑非功能质量属性
3.考虑多种设计选择,并思考为什么选择这种模式,优势劣势分别是什么
4.把设计决策明确写下来
1-1 软件构造过程中的多维度视图
重点:
软件构造的多维视图:从时间,微观还是宏观,编写还是运行三个方面看,每个方面两种共有八个视图。
1.构造时视角
想法->需求文档->规划->代码->可安装程序
代码级视角:代码的逻辑组织
组成视角:代码的物理组织 (代码文件的结构,包括包,库等)
时间片视角:特定时刻的软件形态
时间段视角:软件形态随时间 的变化
构造时,时间片,代码级视角
函数,类,方法等
词汇层面<语法层面<语义层面
语法树(AST):将源代码变为一棵树
构造时,时间段,代码级视角
代码的变化(code churn)Git的单文件历史修改比较
构造时,时间片,组成级视角
源代码的物理组织(文件,目录,包,库文件)
库:
操作系统提供的库
编程语言提供的库
第三方公司提供的库
自己积累的库
构造时,时间段,组成级视角
主要关注:各项软件实体随时间如何变化
版本控制器:Version Control System (VCS)
将每个文件的每个版本储存,并记录软件的每个版本对应各文件的哪个版本
Evolution Graph: (of a SCI or a Software)
记录软件版本的变化以及各个分支分出合并的操作记录
运行时视角
运行时:程序被载入目标机器,开始执行
代码层面:逻辑实体在内存中如何 呈现?
构件层面:物理实体在物理硬件环境中如何呈现?
时间片视角:逻辑/物理实体 在内存/硬件环境中特定时刻的形态如何?
时间段视角: 逻辑/物理实体在内存/ 硬件环境中的形态随时间如何变化?
运行时软件的文件类别:
可执行程序
库
配置文件和数据文件
分布式软件
可执行程序执行方式:
原生机器码:直接执行
解释执行:源码->解释器->执行(BASIC)
解释型字节码:源码->编译->字节码(可执行)->解释器->机器码执行(JAVA)
源码(可执行)->解释器->机器码执行(Perl/Python)
库动态链接的优点:
.类库变化时,不需要重新生成可执行程序
多个运行中程序可共享同一类库, 优化内存使用
运行时,时间片,代码级视角
代码快照图(Snapshot diagram):
描述程序运行时内存 里变量层面的状态
内存信息转储(Memory dump):
将当前内存的内容复制下来保存为文件形式,便于debug,获取程序运行状态信息和分析程序瞬时状态。
运行时,时间段,代码级视角
UML时序图:分析单元之间的调用关系调用顺序和交互。
执行跟踪(Execution tracing):日志技术,记录程序调用记录
运行时,时间片,组成级视角
UML部署图
运行时,时间段,组成级视角
事件日志:系统层面的程序调用
1-2 软件构造的质量目标
软件构造过程中应考虑的重要质量指标
外部质量:影响用户
1.正确性:最重要的质量指标
按照规约(specification)定义的执行,规约内符合的就是正确的,规约外任意都可以。
计算机系统中从抽象层到物理层,每一层保证自己的正确性,同时假设其下层是正确的
保证正确性的方法:
测试和调试:发现不正确、消除不正确
防御式编程:在写程序的时候就确保正确性
形式化方法:通过形式化验证发现问题
2.健壮性:针对异常情况的处理
未被规约覆盖的情况即为“异常情况”
异常情况时,对用户的影响越小越好。
3.可扩展性:对软件的规约进行修改,是否足够容易
规模越大,扩展起来越不容易
可扩展性(Extendibility)的意义:应对未来变化
两种增加可扩展性的编程风格:
简约主义设计
分离主义设计
4.可复用性(Reusability):一次开发,多次使用
5.兼容性(Compatibility):不同的软件系统之间相互可容易的集成
难点:不同软件 有不同的设定/规定
设计方法:保持设计的同构性
标准化的文件组织格式
标准化的数据组织
标准化的用户接口
6.性能(Efficiency)
性能毫无意义,除非有足够的正确性
对性能的关注要与其他质量属性进行折中,因为过度的优化导致软件不再适应变化和复用
过早优化是万恶之源
7.可移植性(Portability):
软件可方便的在不同的技术环境之间移植
8.易用性(Ease of use):容易学、安装、操作、监控
给用户提供详细的指南
结构简单
运行时给用户足够的提示
9.实用性(Functionality)
每增加一小点功能,都确保其他质量属性不受到损失
功能增加过快过多可能导致程序极为复杂、不灵活、占用过多的磁盘空间
10.时效性(Timeliness)
软件应有能力在需求到来之前就更新出功能。
好的软件如果更新过慢错过需求也可能错过用户群体。
11.其他:
可验证性(Verifiability):易于检测故障和追踪错误
完整性(Integrity):能够保证程序包是完整的
可修复性(Repairability):软件错误易于修复
经济性(Economy):构建软件花费人力物力较低
内部质量:影响软件本身和开发者
可读性
可理解性
清晰性
大小
面向质量指标的软件构造技术
折中(Tradeoff):在两种互相冲突的编写风格之间找到平衡
正确的软件开发过程中,开发者应该将不同质量因素之间如何做出折中的设 计决策和标准明确的写下来
虽然需要折中,但“正确性”绝不能与其他质量因素折中。