面向正确性和健壮性的编程(哈工大软件构造)

  在第六章的学习中,我们重点讨论的软件的正确性健壮性的问题,其中涉及到了错误与异常处理、断言与防御式编程、软件的调试、如何进行软件测试以及测试优先的编程原则。下面我就几个在学习过程中较为疑惑的知识点进行总结和介绍。

Java中的 Checked Exception 和 Unchecked Exception

  首先我们介绍异常Exception)的概念,异常即指程序执行过程中的非正常事件,导致程序无法按预想的流程执行。在程序遇到异常时,一般有两种处理方式:1. 将错误信息传递给上层调用者,并报告“案发现场”的信息。2.因为异常情况的发生,直接结束程序,这是程序除了 return 之外的第二种结束程序的方式。
  那么如何区分可检查异常(Checked Exception)和不可检查异常(Unchecked Exception)呢?
  我们一般认为,编译器能够帮助检查并处理的异常是可检查异常,其余的异常为不可检查异常。Java中的异常等级划分入下:
Java中的异常等级划分
  从图中可以看出,所有的异常和错误Error)都实现了一个 Throwable 接口,异常中又根据其抛出的形式具体划分为运行时异常Runtime Exception)和其他异常。在此需要指出的是,运行时异常大都是因为代码本身的bug导致的,编译器无法直接判断出该类异常,只有在运行的时候才能被检测出来,如数组越界、除0错误等等,这类异常可以通过完善代码而避免。由此,Error 类及其子类以及 Runtime Exception 类均属于 Unchecked Exception 类, Exception 的其他子类为 Checked Exception类。
  我们也可以这样理解可检查异常和不可检查异常:程序中所有由内部代码所引起的异常均属于不可检查异常,如空指针、数组越界等等,这类异常需要在代码层面彻底消除,这是正确性的体现。而其余的由外部因素所引起的不可控制的异常为可检查异常,如用户指定的文件不存在等等,这类异常需要我们在程序进行时捕捉并对其做出相应的异常处理机制,保证程序在遇到异常时正常运行,这是健壮性的体现。

断言与防御式编程

  首先我们介绍什么是断言。
  断言assert),实质上是一类程序语句,其允许程序在运行的过程中对自己进行检查,检查内部的不变量,或者传入的前置条件,输出的后置条件等等。其一般用于开发阶段,目的是为了尽快发现程序内部的错误并进行及时的调试。在软件正式发布时,一般会选择关闭断言,避免影响程序性能。
  断言使用的基本形式入下:

	assert condition; 
	//condition为需要判断的条件,若为false,则程序会失败并终止。
	
	assert condition:message; 
	//condition的含义同上,但这行语句会在程序失败时输出我们指定的message语句,以便我们调试。

  在程序的设计过程中,合理使用断言能够让我们高效调试代码,保证代码的正确性。除了检测程序内部的问题之外,我们还可以利用断言对程序的前后置条件进行检测。
  那么在程序设计过程中,什么时候应该使用断言,而什么时候抛出异常呢?在此我们给出一定的引导:

  1. 断言面向正确性,一般用于处理绝不该发生的情况。而异常面向健壮性,用于处理可能发生但不知何时何地会发生的情况。
  2. 在使用断言时,避免使用业务代码,如下:assert list.remove(element),这样会导致我们在软件发布关闭断言时,引起程序内部逻辑错误。
  3. 对于传入的信息,我们根据信息的来源决定使用断言还是异常。若信息来源是外部,则应该优先使用异常处理不合法的信息。若信息来源于可靠的内部源,则优先使用断言处理。

  那么什么是防御式编程呢?这在我们之前的博客中就有所提及。即需要我们在编程过程中,以一定的防御式原则进行,如:防御性拷贝、断言、设置隔离层等方式,尽可能减少程序中会出现的bug。其遵循的原则是:防止bug的最好形式是不引入bug。 与此相对的,由进攻式编程,即在开发阶段尽可能地暴露出所有的bug,保证在开发阶段发现并修复所有bug。其遵循的原则是:今天失败的足够多,明天就不会再失败。

软件测试和测试优先的编程

  软件测试是软件开发过程中十分重要且必不可少的步骤,我们需要在测试阶段对代码进行充分的改进,使其在发布后能有较高的质量。这就类似于现在的很多大型游戏,都需要设定测试服这类专门用于测试的较为不稳定的服务器,通过玩家的亲身体验,对游戏的平衡性以及bug进行调试。
  软件开发过程中的测试有以下几种:

单元测试 --> 集成测试 --> 系统测试 --> 验收测试

	<-- 回归测试 <-- 回归测试 <--

  我们也可以根据测试的方式,将其分为静态测试(不需要运行即可进行)和动态测试(需要测试用例实际运行)。
  也可以根据测试框架分为黑盒测试白盒测试

  1. 黑盒测试:对程序外部的功能进行测试,即根据spec进行测试,需要对测试用例进行等价类划分,保证每一类至少有一个用例。
  2. 白盒测试:对内部代码结构进行测试,需要选择合适的测试用例,保证代码有足够的代码覆盖度、路径覆盖度等等。

  在软件开发过程中,我们一般采用测试优先的编程,即首先对软件进行测试用例的编写,在去编写软件实际的代码,具体步骤如下:

  1. 先根据客户需求写出软件的规约。
  2. 根据软件规约编写符合规约的测试用例。
  3. 最后编写代码程序,编写后执行测试用例,根据测试结果进行修改调试。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值