OO第一单元总结
一.程序结构分析
1.1 类的分析
1.1.1 Expr
为表达式类,将输入的表达式拆分为term类,并将term类相加。
method metrics
method |
CogC |
ev(G) |
iv(G) |
v(G) |
Expr.vareturn() | 8.0 | 1.0 | 5.0 | 5.0 |
Expr.Expr(String, ArrayList) | 20.0 | 1.0 | 10.0 | 13.0 |
Expr.check() | 1.0 | 1.0 | 2.0 | 2.0 |
1.1.2 Term
主要的计算部分,解析term,将term拆分为各个sum,自定义函数,三角函数,数字,x等相乘。
method metrics
Term.Term(String, boolean, ArrayList) |
175.0 |
26.0 |
63.0 |
70.0 |
Term.mult(ArrayList) |
20.0 |
1.0 |
12.0 |
12.0 |
Term.getVariables() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getStrin() |
0.0 |
1.0 |
1.0 |
1.0 |
Term.getispose() |
0.0 |
1.0 |
1.0 |
1.0 |
1.1.3 Variables
基本构成,认为最后的结果就是一个variables的Arraylist,形式为
a X ^ b sin() cos()
method metrics
method |
CogC |
ev(G) |
iv(G) |
v(G) |
Variable.Variable(BigInteger, BigInteger, boolean) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.setSin(ArrayList) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.setPara(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.setCos(ArrayList) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.popara() |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.plusPara(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.istridirect() |
6.0 |
2.0 |
1.0 |
7.0 |
Variable.isempty() |
3.0 |
2.0 |
3.0 |
4.0 |
Variable.getSin() |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.getPow() |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.getPara() |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.getCos() |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.equal(Variable) |
3.0 |
2.0 |
2.0 |
3.0 |
Variable.comparetris(ArrayList, ArrayList) |
7.0 |
4.0 |
3.0 |
4.0 |
Variable.combinSin(ArrayList) |
2.0 |
1.0 |
3.0 |
3.0 |
Variable.combinCos(ArrayList) |
2.0 |
1.0 |
3.0 |
3.0 |
Variable.allequal(Variable) |
6.0 |
1.0 |
4.0 |
7.0 |
Variable.addsin(int, BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.addpow(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.addpara(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Variable.addcos(int, BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
1.1.4 Tri
为sin cos 的类型,内部保存一个variables的Arratlist,为三角函数内部
method metrics
method |
CogC |
ev(G) |
iv(G) |
v(G) |
Tri.Tri(BigInteger, Variable) |
0.0 |
1.0 |
1.0 |
1.0 |
Tri.Tri(BigInteger, ArrayList) |
1.0 |
1.0 |
2.0 |
2.0 |
Tri.Tri(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Tri.setTripow(BigInteger) |
0.0 |
1.0 |
1.0 |
1.0 |
Tri.innerequal(Tri) |
7.0 |
1.0 |
3.0 |
4.0 |
Tri.ifdirect() |
4.0 |
1.0 |
2.0 |
3.0 |
Tri.getVariables() |
0.0 |
1.0 |
1.0 |
1.0 |
Tri.getTripow() |
0.0 |
1.0 |
1.0 |
1.0 |
Tri.compareTo(Tri) |
3.0 |
3.0 |
2.0 |
3.0 |
Tri.allequal(Tri) |
3.0 |
2.0 |
2.0 |
3.0 |
1.1.5 Sum
处理sum函数,有返回其值以variables的Arratlist的形式的方法
method metrics
Sum.Sum(BigInteger, BigInteger, String, ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Sum.calcu() | 2.0 | 1.0 | 2.0 | 3.0 |
1.1.6 Function
处理自定义函数,在读入定义时构建,处理term时运到f,g,h时访问这个类
method metrics
Function.handle() | 1.0 | 1.0 | 2.0 | 2.0 |
Function.getTag() | 0.0 | 1.0 | 1.0 | 1.0 |
Function.getresult(String, ArrayList) | 9.0 | 1.0 | 7.0 | 7.0 |
Function.Function(char, String) | 3.0 | 3.0 | 2.0 | 3.0 |
Function.addva(char) | 0.0 | 1.0 | 1.0 | 1.0 |
1.1.7 Clear
处理空格
method metrics
Clear.clear(String) | 2.0 | 1.0 | 5.0 | 5.0 |
1.1.8 Sim
用于化简的类
method metrics
method |
CogC |
ev(G) |
iv(G) |
v(G) |
Sim.simp(ArrayList) | 8.0 | 1.0 | 7.0 | 7.0 |
Sim.comparetris(ArrayList, ArrayList) | 7.0 | 4.0 | 3.0 | 4.0 |
Sim.combin(ArrayList) | 19.0 | 1.0 | 8.0 | 8.0 |
1.1.9 Print
用于输出最后结果,将variables的Arratlis以字符串的形式输出
method metrics
method |
CogC |
ev(G) |
iv(G) |
v(G) |
Print.tempprint(Tri, String) | 39.0 | 1.0 | 16.0 | 16.0 |
Print.printtri(Tri, String) | 12.0 | 1.0 | 6.0 | 6.0 |
Print.print(ArrayList) | 7.0 | 1.0 | 4.0 | 4.0 |
Print.line(Variable) | 58.0 | 1.0 | 18.0 | 18.0 |
1.2 度量分析
class |
OCavg |
OCmax |
WMC |
Clear |
2.0 |
2.0 |
2.0 |
Expr |
5.666666666666667 |
10.0 |
17.0 |
Function |
2.6 |
6.0 |
13.0 |
Main |
5.0 |
5.0 |
5.0 |
|
10.5 |
18.0 |
42.0 |
Sim |
5.666666666666667 |
8.0 |
17.0 |
Sum |
2.0 |
3.0 |
4.0 |
Term |
12.0 |
49.0 |
60.0 |
Tri |
1.9 |
4.0 |
19.0 |
Variable |
1.8571428571428572 |
7.0 |
39.0 |
Total |
|
|
218.0 |
Average |
3.963636363636364 |
11.2 |
21.8 |
Class metrics
可以发现整体的复杂度很高,相互之间耦合较严重,这点这迭代时的感受十分明显,当对一个类进行修改时,会要求其他的类也进行大量的修改,在未来需要注意对耦合度的降低。
1.3 UML图
因为方法在上面已经写过了,在图中未再画,各个类的方法均为public类型
从UML图中可以看出,整体的架构并不好,与课件中,大部分类都继承一个类的想法差了很多,在添加新的数据的类型,比如出现tan,y等,会复杂很多。
二.bug分析
2.1 公测互测bug分析
第一次公测互测无bug
第二次,未考虑cos(0)的情况,会将cos(0),当作0输出。
第三次,sum函数中min大于max的情况出现错误,自己以为已经处理这种情况,但实际上并未处理。
问题主要出现在设计时,对于特殊情况的考虑不足,不全面。
2.2 复杂度分析
sum函数中的错误方法,v(G)未3,而输出cos(0)的这一错误,v(G)高达18,远高于平均的4.76。出现bug的方法的圈复杂度平均会比未出现的高。
三.测试策略
在本次作业中,主要根据个人考虑特殊情况手动构造测试样例,并未写自动化测试。
而由于个人能力上的不足,手动构造的样例强度并不理想,仅在第三次作业有2次成功的hack。认为最为有效的测试方式还是将自动化测试和手动构造特殊数据相结合。
四.架构设计体验
在第一次的作业中,对于给的实验中的代码并未较好的理解。采用了将需要计算的表达式视作expr,每个expr是由term相加而成,而每个term又是由variable相乘。个人采用的方法,是在expr间,直接通过加号来分割出一个个term,再对term做具体的处理,是乘常数还是x的次数,而对于括号的出现,则将括号内的expr进行递归的计算,将返回的variables与原term中的variabls相乘。这导致了我term中具体分析的代码十分的复杂,使得第二次作业的修改十分困难。
在第二次的作业中,添加了三角函数,以及sum和自定义函数,由于将variable都认为成了a x ^b sin() cos()这一形式,使得原先第一次中对于variable的几乎所有操作都要修改,产生了很大的工作量,让我意识到了原先代码的不合理之处,但由于时间问题,并没有重构。
第三次作业中,由于从第一次开始就是支持递归的,在第三次的作业中,几乎没有改动就直接通过了中测,进行了提交。也让我送了一口气,如果第三次的作业还是添加tan等之类,涉及因子的变化,修改将会十分困难,也让我意识到了好的架构的重要性。
五.心得体会
从没有接触过java直接开始写这两三周的程序,给了我很大的压力,自己时间上的规划也不是很好,导致在架构的思考上十分的不理想,但也是完成了这三周的程序,感谢给了我帮助的同学。
也接触到了面向对象的思想,开始有了一定的理解,荣文戈老师的课上让我对面向对象的理解更加深入了。
希望在接下来的单元中也能顺利度过了。