BUAA_OO Unit1总结
2022OO第一单元总结
第一次作业
作业要求
通过对表达式结构进行建模,完成单变量多项式的括号展开,初步体会层次化设计的思想。
程序架构
类 | 行数 |
---|---|
Add.java | 39 |
MainClass.java | 67 |
MiniList.java | 80 |
Mul.java | 41 |
Parser.java | 152 |
Sub.java | 39 |
度量分析
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Add.add(MiniList, MiniList) | 10.0 | 1.0 | 6.0 | 6.0 |
Add.Add(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Add.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.rmAddOrSub(String) | 56.0 | 5.0 | 18.0 | 21.0 |
MiniList.getVariables(int) | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.MiniList() | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.print() | 54.0 | 4.0 | 18.0 | 21.0 |
MiniList.put(int, BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.setVariables(int, BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.mul(MiniList, MiniList) | 16.0 | 1.0 | 6.0 | 6.0 |
Mul.Mul(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.findAddOrSub(String) | 17.0 | 1.0 | 7.0 | 12.0 |
Parser.findMul(String) | 9.0 | 3.0 | 5.0 | 6.0 |
Parser.findNextOp(int, String) | 2.0 | 1.0 | 3.0 | 4.0 |
Parser.operate(String) | 30.0 | 8.0 | 10.0 | 10.0 |
Parser.parseTerm(String) | 8.0 | 4.0 | 5.0 | 5.0 |
Sub.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Sub.sub(MiniList, MiniList) | 10.0 | 1.0 | 6.0 | 6.0 |
Sub.Sub(String, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Total | 212.0 | 40.0 | 95.0 | 108.0 |
Average | 10.095238095238095 | 1.9047619047619047 | 4.523809523809524 | 5.142857142857143 |
bug分析
自己bug
暂未发现
测试他人bug
使用随机数据对他人的程序进行测试,发现bug主要为对0的0次方判断错误,测试较为有效,但没有结合他人代码架构进行hack
学到了什么
- BigInteger的四则运算不改变其原有的值,结果通过返回值返回
- 从右向左处理表达式可以消除减法和除法造成的错误(左递归)
- String类的方便用法如find(), trim()等
- String转字符串方法:Integer.parseInteger()(可以处理前导零和符号)
第二次作业
作业要求
通过对表达式结构进行建模,完成多项式的括号展开与函数调用、化简,加入了对三角函数、求和函数、自定义函数的处理,进一步体会层次化设计的思想。
程序构架
迭代思路:对表达式的储存结构由原来的数组迭代为ArrayList<Term>, 新增print方法以便输出表达式,新增Term类和Tri类管理因子,新增Func类解析自定义函数,Sub、Mul、Add类对MiniList的处理方式进行迭代,新增Sum类解析求和函数。
类 | Lines |
---|---|
Add.java | 68 |
Func.java | 65 |
MainClass.java | 155 |
MiniList.java | 109 |
Mul.java | 100 |
Parser.java | 313 |
Sub.java | 71 |
Sum.java | 51 |
Term.java | 124 |
Tri.java | 41 |
Total: | 1097 |
度量分析
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Add.add(MiniList, MiniList) | 14.0 | 6.0 | 10.0 | 10.0 |
Add.Add(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Add.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Func.Func(char[], String, int) | 7.0 | 1.0 | 7.0 | 7.0 |
Func.open(String) | 5.0 | 1.0 | 6.0 | 6.0 |
MainClass.main(String[]) | 9.0 | 1.0 | 6.0 | 7.0 |
MainClass.preManage(String) | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.rmAddOrSub(String) | 56.0 | 5.0 | 18.0 | 21.0 |
MainClass.rmWhite(String) | 1.0 | 1.0 | 2.0 | 2.0 |
MainClass.rpPower(String) | 1.0 | 1.0 | 2.0 | 2.0 |
MiniList.clone() | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.merge() | 18.0 | 1.0 | 11.0 | 11.0 |
MiniList.print() | 49.0 | 3.0 | 24.0 | 31.0 |
MiniList.setTerms(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.mul(MiniList, MiniList) | 3.0 | 1.0 | 3.0 | 3.0 |
Mul.Mul(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.mul(Term, Term) | 23.0 | 10.0 | 12.0 | 12.0 |
Parser.constant(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.findAddOrSub(String) | 18.0 | 1.0 | 8.0 | 13.0 |
Parser.findMul(String) | 9.0 | 3.0 | 5.0 | 6.0 |
Parser.findNextOp(int, String) | 2.0 | 1.0 | 3.0 | 4.0 |
Parser.findSum(String) | 1.0 | 2.0 | 1.0 | 2.0 |
Parser.getCos(String) | 16.0 | 3.0 | 7.0 | 7.0 |
Parser.getSin(String) | 17.0 | 3.0 | 8.0 | 8.0 |
Parser.mkZero() | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.openSum(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.operate(String) | 29.0 | 13.0 | 15.0 | 15.0 |
Parser.Parser(Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.parseTerm(String) | 9.0 | 4.0 | 6.0 | 6.0 |
Sub.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Sub.sub(MiniList, MiniList) | 14.0 | 6.0 | 10.0 | 10.0 |
Sub.Sub(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Sum.getResult() | 11.0 | 2.0 | 7.0 | 9.0 |
Sum.Sum(BigInteger, BigInteger, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.clone() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.equalCos(Term) | 24.0 | 9.0 | 17.0 | 21.0 |
Term.equalSin(Term) | 24.0 | 9.0 | 17.0 | 21.0 |
Term.getCoef() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getCos() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getPower() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getSin() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setCoef(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setCos(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setPower(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setSin(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.clone() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.getInPower() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.getOutPower() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.getValue() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.setValue(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.Tri(long, int) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.Tri(long, int, BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Total | 360.0 | 118.0 | 236.0 | 265.0 |
Average | 6.666666666666667 | 2.185185185185185 | 4.37037037037037 | 4.907407407407407 |
bug分析
自己bug
bug: Tri类中若为带符号的整数,则结果可能是含两项Term的MiniList,而我在存进Tri时只取其中第一项,于是出现bug,位于Parser类的getSin和getCos方法,其 Cognitive complexity
(认知复杂度)、 Essential cyclomatic complexity
(基本圈复杂度)、Essential cyclomatic complexity
(基本圈复杂度)、cyclonmatic complexity
(圈复杂度)均远高于平均值。
测试他人bug
注意到部分同学做了三角平方和的优化,于是着重分析他们的判断条件的编写,并从中成功hack
学到了什么
- 如果元素之间的关系确定(项之间为+,因子之间为*),可以使用嵌套HashMap来储存,省略关系(虽然我自己没用)
- 形式化表达与递归下降
- 架构可拓展性的重要性(至少在这一门课)(
是的我重构了) - 浅拷贝容易出锅,深拷贝需要一层一层写clone函数,直到最基础的类(String,int等)
- 正则表达式的贪婪模式与懒惰模式(如果"(.+)(.+)",那么group(0) = group(1), group(2) = "")
第三次作业
作业要求
代码架构
类 | Lines |
---|---|
Add.java | 68 |
Func.java | 87 |
MainClass.java | 156 |
MiniList.java | 155 |
Mul.java | 94 |
Parser.java | 344 |
Sub.java | 71 |
Sum.java | 51 |
Term.java | 118 |
Tri.java | 40 |
Total: | 1184 |
本次迭代主要将Tri类中的属性更新为MiniLIst,以便储存嵌套表达式,同时在因子等类中加入equal()方法,便于判断合并条件。
度量分析
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Add.Add(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Add.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.preManage(String) | 0.0 | 1.0 | 1.0 | 1.0 |
MiniList.getTerms() | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.Mul(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Mul.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.Parser(Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.constant(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.mkZero() | 0.0 | 1.0 | 1.0 | 1.0 |
Parser.openSum(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Sub.Sub(String, String, Func, Func, Func) | 0.0 | 1.0 | 1.0 | 1.0 |
Sub.getResult() | 0.0 | 1.0 | 1.0 | 1.0 |
Sum.Sum(BigInteger, BigInteger, String) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.clone() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getCoef() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getCos() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getPower() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.getSin() | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setCoef(BigInteger) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setCos(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setPower(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Term.setSin(ArrayList) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.Tri(MiniList) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.clone() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.getInside() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.getOutPower() | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.setInside(MiniList) | 0.0 | 1.0 | 1.0 | 1.0 |
Tri.setOutPower(int) | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.rmWhite(String) | 1.0 | 1.0 | 2.0 | 2.0 |
MainClass.rpPower(String) | 1.0 | 1.0 | 2.0 | 2.0 |
MiniList.clone() | 1.0 | 1.0 | 2.0 | 2.0 |
MiniList.printIn() | 2.0 | 1.0 | 2.0 | 2.0 |
Parser.findNextOp(int, String) | 2.0 | 1.0 | 3.0 | 4.0 |
Parser.findSum(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Parser.matchC(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Parser.matchF(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Parser.matchG(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Parser.matchH(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Parser.matchS(String) | 2.0 | 2.0 | 2.0 | 3.0 |
Tri.equal(Tri) | 2.0 | 2.0 | 2.0 | 3.0 |
Mul.mul(MiniList, MiniList) | 3.0 | 1.0 | 3.0 | 3.0 |
Term.equal(Term) | 4.0 | 3.0 | 4.0 | 5.0 |
Func.open(String) | 5.0 | 1.0 | 6.0 | 6.0 |
Func.Func(char[], String, int) | 7.0 | 1.0 | 7.0 | 7.0 |
Func.preSplit(String) | 8.0 | 1.0 | 6.0 | 6.0 |
MiniList.equal(MiniList) | 8.0 | 5.0 | 5.0 | 6.0 |
MainClass.main(String[]) | 9.0 | 1.0 | 6.0 | 7.0 |
Parser.findMul(String) | 9.0 | 3.0 | 5.0 | 6.0 |
Parser.parseTerm(String) | 9.0 | 4.0 | 6.0 | 6.0 |
Parser.getCos(String) | 11.0 | 3.0 | 6.0 | 6.0 |
Parser.getSin(String) | 11.0 | 3.0 | 6.0 | 6.0 |
Sum.getResult() | 11.0 | 2.0 | 7.0 | 9.0 |
MiniList.merge() | 12.0 | 1.0 | 7.0 | 7.0 |
Mul.mul(Term, Term) | 13.0 | 8.0 | 8.0 | 8.0 |
Add.add(MiniList, MiniList) | 14.0 | 6.0 | 10.0 | 10.0 |
MiniList.isOneterm() | 14.0 | 8.0 | 9.0 | 15.0 |
Sub.sub(MiniList, MiniList) | 14.0 | 6.0 | 10.0 | 10.0 |
Term.equalCos(Term) | 16.0 | 9.0 | 5.0 | 9.0 |
Term.equalSin(Term) | 16.0 | 9.0 | 5.0 | 9.0 |
Parser.findAddOrSub(String) | 18.0 | 1.0 | 8.0 | 13.0 |
Parser.operate(String) | 29.0 | 13.0 | 15.0 | 15.0 |
MiniList.print() | 38.0 | 3.0 | 17.0 | 24.0 |
MainClass.rmAddOrSub(String) | 56.0 | 5.0 | 18.0 | 21.0 |
Total | 356.0 | 144.0 | 232.0 | 275.0 |
Average | 5.650793650793651 | 2.2857142857142856 | 3.6825396825396823 | 4.365079365079365 |
Parser类中的operate()方法经过拆解后,平均复杂度明显下降。
bug分析
自己的bug
在正则表达式中通过逗号来匹配函数表达式出锅(我不知道中测是怎么全过的),我认为这是测试与coding逻辑的问题,与类的方法的复杂度等无关。
别人的bug
主要是三角函数中化简过头了,少加了括号,或者sum没有注意到上下限的限制(即没有限制)
学到了什么
- 新增方法而不是一味地使用if else语句可以极大地提高代码的可阅读性和可拓展性
架构设计体验
第一次作业中我使用数组来储存表达式,虽然方便,但可迭代性很差,以至于第二次作业中的储存结构和计算方式都进行了重构
第二次作业到第三次作业,由于第二次作业中储存结构设计合理,迭代只需要在Tri中递归调用MiniList类即可,无奈对正则表达式匹配漏洞的疏忽使设计任存在bug,但迭代过程比较顺畅,总体还是比较成功
类与类之间的关系可以有很多种,父类抽象子类具体的原则使得代码层次清晰,单一职责原则能简化测试,提高代码可阅读性,而更多的关系还有待进一步探索
总体而言对面向对象编程的体会还是很欠缺,感觉自己的代码大部分还是面向过程编程,没有pre冒险的那种感觉
心得体会
封装、多态这些听起来很高级的词汇居然有一天也会被应用到我的代码里,千余行代码也使我收获不小的成就感。作业除了让我掌握了完成它需要的知识,也让我有了初步的工程架构设计的能力。
感谢助教和老师们的辛苦付出,也感谢xrb、syq等hxd的援助和无情hack