(二)实现被测程序ArrayCompare代码
本节主要为大家梳理本测试项目的目标程序ArrayCompare的功能结构及具体代码实现。
实验简介
本节主要为大家梳理本测试项目的目标程序ArrayCompare的功能结构及具体代码实现。
实验目的
(1) 掌握概要设计与接口设计的基本方法。
(2) 能够熟练快速地定位和梳理代码逻辑。
(3) 对代码功能进行解读,进而达到测试的目的。
实验流程
1. 代码结构图
2. 代码实现原则
我们将基于如下思路来进行程序的整体架构和接口设计:
(1) 合理使用面向对象特性,保证可测试性和模块的独立性。
(2) 高重用,低耦合。
(3) 结构合理,方法之间的调用深度不超过5层。
(4) 命名规范合理,见名知意。
(5) 不使用多态性,不过度使用面向对象设计设计原则。
(6) 不使用太多内置API,尽量自主实现所有功能。
3. 定义代码实现类
由上图可知,该程序必须包含4个源代码文件:
(1) MainRun:程序运行主入口,用于用户输入数据和调用CompareHandle.mainCompare(1,2).
(2) StringHandle:字符串处理类,用于输入数据,解析字符串成数组,判断是否为数值.
(3) CompareHandle:程序比较主类,用于比较数组中的值及判断各种可能的情况.
(4) ArrayHandle:数组处理类,用于数组排序和数组值的比较.
4. 实现程序主入口:MainRun.java
package com.woniuxy.compare;
public class MainRun { public static void main(String[] args) { StringHandle sh = new StringHandle(); CompareHandle ch = new CompareHandle(); // 提示用户输入字符串 Integer[] a = sh.inputString(); Integer[] b = sh.inputString();
// 对用户输入的内容进行比较 String result = ch.mainCompare(a, b); System.out.println(result); } } |
5. 字符串处理类:StringHandle.java
package com.woniuxy.compare; import java.util.Arrays; import java.util.Scanner; import java.util.Vector; public class StringHandle{ // 从控制台输入字符串 public Integer[] inputString() { Integer[] result; System.out.println("请输入一个字符串:"); Scanner sc = new Scanner(System.in); String source = sc.nextLine(); if (source.length() < 1) { System.out.println("你的输入不合法,将强制退出."); System.exit(1); result = null; } else { Integer[] array = this.splitString(source, ","); if (Arrays.equals(array, null)) System.out.println("输入不合法"); result = array; } return result; } // 将字符串解析成数组 // 模拟实现字符串处理方法split,为方便测试,所以自行实现 public Integer[] splitString(String source, String delimiter) { Vector<Integer> vector = new Vector<Integer>(); int position = source.indexOf(delimiter); while (source.contains(delimiter)) { String value = source.substring(0, position); if (this.isNumber(value)) { vector.add(Integer.parseInt(value)); } else { System.out.println("你的输入不合法,将强制退出."); System.exit(1); // 如果不想强制退出程序,也可以设置一个特别的值用以说明输入不合法 // Integer[] result = {11111}; // return result; } source = source.substring(position + 1, source.length()); position = source.indexOf(delimiter); } vector.add(Integer.parseInt(source)); Integer[] array = new Integer[vector.size()]; vector.copyInto(array); return array; } // 检查字符串是否可正常转换为数字 public boolean isNumber(String source) { int minus = 0; // 统计负号的个数 int point = 0; // 统计小数点的个数 for(int i=0; i<source.length(); i++){ int code = source.charAt(i); // 获取每个字符的ASCII码 // 如果某个字符不属于0-9或负号或小数点,则可以判定为无效数字 if (code<45 || code > 57 || code == 47) return false; // 统计字符串中负号和小数点的个数 if(code == 45) minus++; if(code == 46) point++; } // 如果字符串中的负号或小数点超过1个,则无效 if(minus > 1 || point > 1) return false; // 如果有负号,但是负号不在第一位,则无效 if(minus == 1 && source.charAt(0) != 45) return false; // 如果有小数点,但是小数点在最后一位,则无效 if(point == 1 && source.charAt(source.length()-1) == '.') return false; // 如果以上情况都未出现,则说明是正确的数字 return true; } }
6. 数组比较类:CompareHandle.java
package com.woniuxy.compare; public class CompareHandle { // 输入按一定规律分隔的字符串并将其转换成数组 public String mainCompare(Integer[] a, Integer[] b) { String result = ""; int alength = a.length; int blength = b.length; if (alength == 0 || blength == 0) result = "结果: 数组长度为零."; else if (alength != blength) result = "结果: 数组长度不一致."; else { int compareResult = this.mainCheck(a, b); if (compareResult == 1) result = "结果: 数组相同."; else if (compareResult == 2) result = "结果: 数组排序后相同."; else result = "结果: 数组不同."; } return result; } // 比较两个数组是否相同 public int mainCheck(Integer[] a, Integer[] b) { int flag = 0; ArrayHandle ah = new ArrayHandle(); if (ah.arrayCompare(a, b)) flag = 1; // 不用排序,自然相同 else { Integer[] arraya = ah.arraySort(a); Integer[] arrayb = ah.arraySort(b); if (ah.arrayCompare(arraya, arrayb)) flag = 2; // 排好序后相同 else flag = 3; // 排序后也不同 } return flag; } }
7. 数组处理类:ArrayHandle.java
package com.woniuxy.compare; public class ArrayHandle { // 对两个数组进行排序(冒泡排序) public Integer[] arraySort(Integer[] array) { Integer i, j, temp, sorted; for(i=0; i<array.length-1; i++) { sorted = 0; for(j=0; j<array.length-i-1; j++) { if(array[j] > array[j+1]) { sorted = 1; temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } if (sorted == 0) break; } return array; } // 对两个数组进行比较 public boolean arrayCompare(Integer[] a, Integer[] b) { int i; boolean flag = true; for (i=0; i<a.length; i++) { if (a[i] != b[i]) { flag = false; break; } } return flag; } }
8. 运行ArrayCompare
上述代码的实现并非是最标准的代码,也并非没有Bug,当然,这也正好是留给大家去测试的点。由于我们需要模拟相对有多层次调用的特征,笔者在设计代码时特意将一些程序作了复杂化处理。请读者朋友更多关注于程序的接口关系调用和接下来的代码级测试实施上,而非代码本身的实现逻辑。
当我们的代码实现完成后,不妨直接运行MainRun类,看看能否得到本程序的运行结果。要完成接下来的测试开发工作,请首先保证整个程序代码的完整性和正确性。
思考练习
(1) 上述代码是否存在明显的BUG?有的话请修复。
(2) 一个标准的软件开发过程是怎样的?试着总结一下。