软件工程网络15结对编程作业
题目要求:
码云链接
201521123011祁泽文码云地址:https://gitee.com/jiaowoxiaotiancai/software-engineering
201521123009张晨晨码云地址:https://gitee.com/z1450429983/events
需求分析:
1.实现分数整数的四则运算。
2.实现错误排查,以及正确率的统计。
3.实现新增功能括号运算,减少重复题目。
4.进行代码的单元测试,检查覆盖率。
clone过程:
[改]修改clone部分:
类图:
1.参考代码的不足之处:
1.改进现有代码
【参考】个人博客地址2:http://www.cnblogs.com/belong033 ,源代码:https://coding.net/u/Belong033/p/java-third/git
不足之一:
从以上可以看出这位同学已经有了main函数,又在类(这里有两个类createInteger创建整数类,createFraction创建分数类)中又写了main方法,使得整体代码的可读性不高。
不足之二:
并且在类的main方法中包含了所有的运算方法(加减乘除)导致:
1.测试时main方法出错却不知道哪一个代码块出现问题,不能分布排查。
2.有大量重复代码,使代码的冗长,降低运行效率。
不足之三:
这里的辗转相除法感觉出现了逻辑问题,运行时结果是错误的。
2.修改与重构:
重构1(针对方法的重构):
将两个类中的main方法删除(这里以createInteger为例),将加减乘除单独写成方法,这样便可以一目了然,再在main中调用createInteger的方法。用switch后,那段判断判断正误的if循环也只需要写一遍就可以了,大大简化了之前的代码。
重构2(针对逻辑问题的重构):
对于问题3辗转相除法求公约数修改后的代码,最后运行结果的截图如下图:
3.单元测试:
第一次测试:
可以看出第一次做单元测试时有一个错误,是除法产生的,再去重新测试除法时发现了所返回的数的格式转换问题。
第一次测试问题修正:
检查代码发现是因为,除法会产生分数所以我返回的是String型,而我的result是int型,所以再转换时出现了格式错误。
修改时有两个想法:1.用数组储存分子分母,返回一个整型,在main函数调用时采用```i1+“/”+i2````的格式输出。但这样就把除法搞复杂了。2.将所有方法(加减乘除)都返回String型,result也定义为String型,这样相对简单,代码阅读性也高。
第二次测试:
4.检测覆盖率:
[改]修改:
【功能改进与扩展】
思维导图:
增加括号运算符:
虽然在参考代码中只找到了逻辑错误,没找到逻辑泥球,但在自己写括号运算时,体验到了什么叫逻辑泥球,在用栈写括号运算时,可能想的方式不够好导致了一堆if,else的循环,一个嵌套一个。于是不用栈了。
//逻辑泥球
Integer s = null;
for (int i = 0; i < arr.length; i++) {
if ( stack.isEmpty()){
if(arr[i].equals("("))
continue;
else
stack.push(arr[i]);
}
else if (arr[i].equals(")") ){
String r1 = stack.pop();
String r2 = stack.pop();
String r3 = stack.pop();
char r=r2.charAt(0);
Integer a = Integer.valueOf(r1);
Integer b = Integer.valueOf(r3);
if(stack.isEmpty()){
switch(r){
case '+':
m=a+b;
break;
case '-':
m=a-b;
break;
}
String l1=arr[i+1];//*/
char l=l1.charAt(0);
String l2=arr[i+2];
Integer l3= Integer.valueOf(l2);
switch(l){
case '*':
s=m*l3;
break;
case '/':
Integer A=new Integer(5);
int m1=A.intValue();
int l4=A.intValue();
String s1=createInteger.dev(m1, l4);
s= Integer.valueOf(s1);
break;
}
}
else {
String r4 = stack.pop();//fuhao
String r5 = stack.pop();
char l=r4.charAt(0);
Integer l3= Integer.valueOf(r5);
switch(l){
case '*':
s=m*l3;
break;
case '/':
Integer A=new Integer(5);
int m1=A.intValue();
int l4=A.intValue();
String s1=createInteger.dev(l4, m1);
s= Integer.valueOf(s1);
break;
}
}
}
}
下图是修改后的代码,但是还是不够完善。因为用switch规定了产生算式的格式如:
case 1:str="("+a+"+"+b+")*"+c+"=";break;
没有用二叉树随机生成符号或算式。
【附加题】
增加一个运算符(乘方)
[改]添加:效能分析
【两人合作】
照片:
总结(结对编程感想)
1.两人确定了代码规范,以Tab键为准。体验了这次结对编程,在领航员和驾驶员两个角色下互相转换,说实话并没有体验到1+1>2。可能由于两人编程基础都相对薄弱,所以没有思维的碰撞,更多的交流只是一个人听从另一个人的想法。
2.这次选取的代码结构相对不太友好,前期两人都忙于重构代码,几乎是重写了整个代码的结构,让我们认识到一个代码好的风格的重要性,如果将所有的方法写在一个main方法中,不仅测试难以测试出具体出错的地方,也不方便对功能的增删改查。
3.通过和已经工作的人对比psp发现,需求分析方面所用时间太少,而编写代码时间太长。这也是需要改进的地方。