[软件构造]实验回顾:Lab4

实验目标:Debugging, Exception Handling, and Defensive Programming

本次实验重点训练学生面向健壮性和正确性的编程技能,利用错误和异常处理、断言与防御式编程技术、日志/断点等调试技术、黑盒测试编程技术,使程序可在不同的健壮性/正确性需求下能恰当的处理各种例外与错误情况,在出错后可优雅的退出或继续执行,发现错误之后可有效的定位错误并做出修改。
实验针对Lab 3中写好的ADT代码和基于该ADT的三个应用的代码,使用以下技术进行改造,提高其健壮性和正确性:
⚫ 错误处理
⚫ 异常处理
⚫ Assertion和防御式编程
⚫ 日志
⚫ 调试技术
⚫ 黑盒测试及代码覆盖度

第一部分:异常处理

异常的定义

对于异常处理,我的感受是,如果想做的很复杂,那是真的可以做的很复杂;要是稍微做的简单些,那是真的能做的非常简单。我的Lab4做得比较仓促,就没有把异常种类分的很细,因为我觉得,能让人理解的清晰的异常抛出机制就很优秀了,不需要分的过于精细:毕竟异常里边还有prompt和gripe,通过这两个就可以看出异常是怎么触发的了。定义的异常类型:InputInvalidException, ParameterNumberException, ConstructFaliureException

public class InputInvalidException extends Exception {
	
	public final String prompt = "Input invalid Exception: ";
	public String gripe = "Unknown exception";
	
	public InputInvalidException() {}
	
	public InputInvalidException(String gripe) {
		this.gripe = gripe;
	}
}

异常处理的具体代码

这个实验里边的异常也就那么几种,参数数量不对,类型不对,读文件失败,这些异常会触发ConstructFaliureException,使整个构建失败。
下面是StellarSystem里边的一段代码,作为例子:

    	try {
    		if(strs.length != 3) {
    			log.severe("Parameters number not right: Stellar");
    			throw new ParameterNumberException("Parameters number not right: Stellar", 3, strs.length);
    		}
    		else{
    			double R, m;
    			try {
    				R = Double.valueOf(strs[1].toString());
    			}catch(NumberFormatException e) {
    				log.severe("Radius is not a number: Stellar");
    				throw new InputInvalidException("Radius is not a number: Stellar");
    			}
    			if(R > 10000 && !strs[1].contains("e") || R < 10000 && strs[1].contains("e")) {
    				log.severe("Radius number format invalid: Stellar");
    				throw new InputInvalidException("Radius number format invalid: Stellar");
    			}
    			
    			try {
    				m = Double.valueOf(strs[2].toString());
    			}catch(NumberFormatException e) {
    				log.severe("Mass is not a number: Stellar");
    				throw new InputInvalidException("Mass is not a number: Stellar");
    			}
    			if(m > 10000 && !strs[2].contains("e") || m < 10000 && strs[2].contains("e")) {
    				log.severe("Mass number format invalid: Stellar");
    				throw new InputInvalidException("Mass number format invalid: Stellar");
    			}
    			
    			this.addCenter(new Stellar(strs[0].trim(), R, m));
    		}
    	}catch(InputInvalidException e) {
    		System.out.println(e.prompt + e.gripe);
    		ex = true;
    	}

其中ex是一个布尔型变量,用于记录构建过程中是否出现了异常。如果一直都没有出现异常,那么构建成功。如果出现了异常,也可以汇总之后再使构建失败。

    	if(ex) {
    		log.severe("Construction failed.");
    		throw new ConstructFaliureException();
    	}

第二部分:断言,checkRep

在这部分中,使用断言技术,保证我们的程序执行正确。由于在实验3中,我已经编写了较全面的checkRep,包括每个方法执行完之后的检测,所以做的工作不是很多。

第三部分:日志

在Lab3中,我在多数方法中都编写了向控制台的输出,现在只需要把他们输出到日志里边即可。
日志记录以下信息:
⚫ 所有的异常/错误:发生的时间、异常/错误类型、异常/错误发生的类名和方法名,异常/错误的具体信息、异常/错误处理的结果;
⚫ 对多轨道系统的所有操作,包括:读取文件、增加/删除轨道、增加中心点物体、增加/删除轨道上的物体、增加/删除物体之间的关系、跃迁等。
日志记录信息,按照严重程度,分为不同的等级,我这里只用了info,warning,severe三种。关于日志的操作,比较基本,就是调用Java自带的logger写日志就行了,网上有很多参考资料,大多数都可以用。
为日志添加FileHandler并初始化的过程:

	public static FileHandler fh = null;
	static {
		try {
			fh = new FileHandler("src\\logging\\AtomStructure.txt");
		} catch (IOException e) {
			e.printStackTrace();
		}
		fh.setFormatter(new SimpleFormatter());
	}

在日志查询的过程中,用字符串是否存在子串的方法就可以有效过滤了。

第四部分:测试

根据课件上的等价类和边界值的测试思想,为各ADT添加了测试用例。这次的测试用例都是针对异常抛出设计的,所以有的时候checkRep在程序中会报错,这个也是没有办法,只能在测试的时候将其注释掉。这个部分没什么难度。

第五部分:用工具检查潜在Bug

这部分使用SpotBugs对代码进行静态检查,检查代码中潜在的危险与漏洞。SpotBugs检查我的代码,报告说明了我的程序中两个不好的地方:
1.在main中,调用三个APP函数参数传null值
解决方法:将没有用的String[] args重新传给APP的主函数

		switch(choice) {
		case 1:
			StellarSystemAPP.main(args);
			break;
		case 2:
			AtomStructureAPP.main(args);
			break;
		case 3:
			SocialNetworkCircleAPP.main(args);
			break;

2.对RuntimeException和checked exception混淆处理
解决方案:分开处理unchecked和checked异常

			try {
				Thread.sleep(10);
			} catch (RuntimeException e) {
				e.printStackTrace();
			}
			catch (Exception e) {
				e.printStackTrace();
			}

通过这些报告,可以给我一个提示,让我在以后的编程中少写出这种容易引起错误的风格的代码,对我的编程习惯还是有帮助的。

第六部分:给定程序的调试

这部分在我看来很无聊,也很累。第一,你需要读懂别人的代码,代码没有注释的时候这个就比较费时间。第二,代码的错误千篇一律,让人觉得很烦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Y86 Tools (Student Distribution) Copyright (c) 2002, R. Bryant and D. O Hallaron, All rights reserved. May not be used, modified, or copied without permission. This directory contains the student distribution of the Y86 tools. It is a proper subset of the master distribution, minus the solution files found in the master distribution. yas Y86 assembler yis Y86 instruction (ISA) simulator hcl2c HCL to C translator ssim SEQ simulator ssim+ SEQ+ simulator psim PIPE simulator y86-code/ Examples programs and and benchmark testing scripts ptest/ Scripts for detailed automated regression testing 1. Building the Y86 tools The Y86 simulators can be configured to support TTY and GUI interfaces. A simulator running in TTY mode prints all information about its run-time behavior on the terminal. Hard to understand what s going on, but useful for automated testing, and doesn t require any special installation features. A simulator running in GUI mode uses a fancy graphical user interface. Nice for visualizing and debugging, but requires installation of Tcl/Tk on your system. To build the Y86 tools, perform the following steps: NOTE: If your instructor prepared this distribution for you, then you can skip Step 1 and proceed directly to Step 2. The Makefile will already have the proper values for GUIMODE, TKLIBS, and TKINC for your system. Step 1. Decide whether you want the TTY or GUI form of the simulators, and then modify ./Makefile in this directory accordingly. (The changes you make to the variables in this Makefile will override the values already assigned in the Makefiles in the seq and pipe directories.) Building the GUI simulators: If you have Tcl/Tk installed on your system, then you can build the GUI form by initializing the GUIMODE, TKLIBS, and TKINC variables, as appropriate for your system. (The default values work for Linux systems.) Assigning GUIMODE=-DHAS_GUI causes the necessary GUI support code in the simulator sources to be included. The TKLIBS variable tells gcc where to look for the libtcl.so and libtk.so libraries. And the TKINC variable tells gcc where to find the tcl.h and tk.h header files. Building the TTY simulators: If you don t have Tcl/Tk installed on your system, then build the TTY form by commenting out all three of these variables (GUIMODE, TKLIBS, and TKINC) in the Makefile. Step 2: Once you ve modified the Makefile to build either the GUI or TTY form, then you can construct the entire set of Y86 tools by typing unix> make clean; make 2. Files Makefile Builds the Y86 tools README This file misc/ Source files for the Y86 assembler yas, the Y86 instruction simulator yis, and the isa.c file that is used by the -t option of the processor simulators to check the results against the ISA simulation. seq/ Code for the SEQ and SEQ+ simulators. Contains HCL files for labs and homework problems that involve modifying SEQ. pipe/ Code for the PIPE simulator. Contains HCL files for labs and homework problems that involve modifying PIPE. y86-code/ Example .ys files from CS:APP and scripts for conducting automated benchmark teseting of the new processor designs. ptest/ Automated regression testing scripts for testing processor designs.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值