软件构造与代码实现
17-18-软件构造和代码设计
软件构造定义:
通过编码,验证,单元测试,集成测试,和调试等工作的结合,生产可工作的,有意义的软件详细创建过程。简单说软件构造是以程序为主完成的综合性任务。
软件构造包含的活动
①详细设计;
②编程:软件构造的核心活动,目的是产生高质量代码程序。
③测试:
1.单元测试:对程序单元进行正确性检验
2.集成测试:对系统接口进行正确性检验 (集成测试策略:1.大爆炸集成;2.增量集成。增量集成又分为自顶向下、自底向上、持续集成。
④调试:1.重现问题;2.诊断缺陷;3.修复缺陷(一次只修复一个缺陷)。
⑤代码评审:由同行专家对代码的系统检查。
1.正式评审:多个同行专家召开评审会议。
2.轻量级评审:评阅者直接阅读计算机屏幕代码。
3.结对编程:两个程序员挨着坐在一起共同协作进行软件构造活动。
⑥集成与构建:将分散的程序基本单位集成和构建为构件,子系统和完整系统。
⑦构造管理:
1.构造计划。
2.度量(围绕源代码展开,包括:1.类与方法的复杂度,类和方法的代码行数和注释行数)
3.配置管理(相关制品:源代码基线;数据基线;可执行程序)。
软件构造的实践方法
重构(21):修改软件系统的严谨方法,它在不改变代码的外部表现的情况下改进其内部结构。
重构的时机:①添加新功能时;②发现了缺陷进行修复时;③进行代码评审时。
测试驱动开发:编写代码之前,优先完成该段代码的测试代码,完成测试后,再编写代码程序,并在编写中重复执行代码程序以验证代码的正确性。
步骤:
编写测试代码,编译测试代码,编译无法通过
最小化编写正常代码,使测试代码通过编译
运行测试代码,测试用例失败
最小化修改正常代码,满足测试用例
运行测试代码,测试用例通过
重构正常代码
优点:①提高程序的正确性和可靠性;②提高设计质量;③提高生产力
结对编程:两个程序员挨坐在一起共同协作进行软件构造活动。分为Driver(驾驶员)负责代码编写和Observer(观察员)进行评审。每隔一段时间两个程序员的角色可以互换。
优点:提高程序质量,降低程序缺陷率,减少返工和修复成本。
程序代码质量:
易读性(最重要目标);易维护型;可靠性;性能;安全性。
代码设计:(给定代码段示例,对其进行改进或者发现其中的问题)
易读性:
1)格式:缩进和对齐、将相关逻辑组织在一起、语句分行。
2)变量命名:惯例和规则。
3)注释:文档注释,内部注释。
易维护性:
1)小型任务:分解为多个高内聚、低耦合的小型任务。
2)封装复杂决策:使用布尔变量简化复杂决策,有意义的名称来封装决策,表驱动编程。
3)数据使用:变量与目的对应。
4)明确依赖关系。
可靠性:
1)契约型设计。
2)防御型编程。
使用辅助模型:
决策表、伪代码、流程图。
表驱动编程:
将复杂决策包装为决策表,根据决策表的信息进行编程,使程序变得清晰简单洁,只需维护表数据即可。
契约式设计(断言式设计):
一个方法或函数,在前置条件满足的情况下执行,完成后后置条件满足,则该方法或函数就是正确的,可靠的。
异常方式:代码开始执行前检查前置条件是否满足,不满足抛出异常,执行结束后判断后置条件是否满足,不满足也抛出异常。
断言方式:
Java提供断言语句:assert(Expression1):(Expression2)。Expression1为布尔表达式,为true不抛出异常,为false抛出AssertionError:Expression2。
异常比断言灵活得多,可以用Java自定义异常。
防御式编程
当外界发生错误时,保护方法内部不受损害。会增加代码的复杂度,降低易读性和性能,但是增加了可靠性。
与契约式设计的异同:
同:都要检测输入参数的有效性;
异:防御性编程将所有与外界的交互(不仅是前置条件)都纳入防御范围,并且不检查输出和后置条件。
MockObject:本质上是一个简单的桩,用于代替测试的类,将测试的方法独立出来。
代码复杂度度量:
流程图中V(G)=E-N+2
N为节点数,E为边数。