OO第一单元总结
一、程序结构分析
- 总的来说,这一学期我才开始正式的接触面向对象的思想,直到pre才开始正式的实践,所以这次作业可能写的有一些混乱,第三次作业也进行了大量重构。
1. 第一次作业
- 关于程序结构:
仅仅使用了四个类,之间也没有继承关系,仅仅在Term类中采用了Comparable借口进行排序,使用了TreeSet容器进行排序和合并同类项;
Term类中采用二元组进行存储(系数和指数);
PolyString类类似一个传入字符串生成Poly对象的一个工厂,Poly类储存了一个Term的容器,和一个求导方法;
程序逻辑也非常简单,PolyString生成Poly对象,Poly类逐项求导,生成一个新的Poly类,最后重写toString方法输出。
第一次作业也比较简单,所以合并同类项和第一项为正,即可拿到100分。
- 关于程序复杂度:
可以看到,复杂度最高的方法是字符串的分析和处理,虽然使用了正则表达式捕获组,但是还是过于复杂,中间使用的条件分支语句和循环语句也不少。
把字符串的处理分解开来可能是个更好的办法。
2. 第二次作业
-
在第一次的烂摊子上进行了“迭代开发”,还是这四个类;
不同的是在第一次作业的基础上进行了WF判断,于是对正则表达式进行了“升级”,严格按照参考书的形式化逻辑编写了正则表达式,那么,match不到的必是WF;
由于本次作业中加入三角函数,于是Term也相应变成了四元组,相应的,求导方法也进行了重写。
程序总体思路上没怎么变,至于化简上我也没有考虑三角函数的归一化简,仅仅考虑合并同类型,做到正确度优先;
最终拿到94分。
-
可以看到,程序最复杂的地方依然是字符串分析和处理的方法,由于第二次作业的字符串复杂度大于第一次作业,相应的第二次作业的总复杂度也有提升。
值得一提的是,第二次作业的字符串输出的复杂度也有不少提升。
由于前两次作业较简单,完全没有考虑到设计隐患对将来的迭代开发有什么影响,于是给自己第三次作业挖了大坑。
3. 第三次作业
重构!!!!
这次程序确实有些复杂,复杂到生成的图确实没法看了();
本次作业由于引入了嵌套求导,所有必须要采用“递归”的思想。
一开始我由于对正则表达式理解不够透彻,试着用正则表达式匹配全串,结果发现根本无法完成,用自动机又过于繁琐;
于是我就想到了利用加减号来分割项目,利用乘号来分割因子,利用括号来递归嵌套生成表达式,生成和求导都遵循深度有限原则;
利用多层工厂来生成需要的对象,上级对象存储下级对象的一个容器;
新建“因子”(Factor)接口,不同类型的接口都使用这个借口,便于归一化处理。
同时使用几个工具类(StringXX,MyString)封装了一些需要的字符串操作,提高代码复用。
这次作业使用了Exception进行错误处理,但是这里出现了一个Bug,我们第二部分再谈。
这次作业也由于我个人能力有限,仅仅进行了非常有限的化简,对于括号之类的处理完全没有进行
最终由于强侧挂了一个测试点,惜得90分。
-
从图中看出,整体的方法复杂度降低不少,但是处理字符串的方法还是过于复杂,几个处理字符串的类耦合度过高;
虽然做到了一些模块化处理,但是还是没有做到很好,这也需要在后续的学习中一步一步提升面向对象编程的能力。
二、BUG分析
- 本单元作业前两次都没有发现BUG,着重就第三次强测中出现的这一个BUG展开讨论。
1. 前两次作业
主要在自己进行测试时发现正则表达式捕获组判断不全面,增加了相关的检查判断,修复了所有BUG。
2. 第三次作业
由于进行分层处理,疏忽了一个在逻辑方面的致命问题,测试时也忘记了这个问题“cos(- 1)”这种类型的问题;
结果我先去空格后利用正则表达式判断的问题在强测中暴露了出来,在bug修复环节,我及时给这个问题打了补丁,
但是在设计时忽略了这么一个这么重要的问题,也是值得我思考,至少自己的逻辑应该更加严谨。
而且后打的这个补丁,完全与之前的设计思维相悖,不得不新增了几个标记变量,由于一点的逻辑漏洞,而不想重写代码,所造成的后果也是很严重的。
三、互测分析
-
本人三次作业均没有被Hack,所以从发现他人bug来展开讨论。
(由于不清楚分房机制,我也不知道我自己在什么等级的房间)
第一次作业我尝试使用自动测试,由于个人能力一般和其他人能力太强,什么Bug也没找到,最后整个房间也没发现Bug;
第二次作业我继续尝试使用自动测试,什么Bug也没找到,反而我手动提交一组样例,成功hack;
说明自动生成的测试样例针对性不强,如果需要针对性强的也需要自己调整,不如手动调整。
所以说针对比较简单的作业,不如自己直接编写一些测试样例进行测试,自动化测试的要求并没有那么高,笔记
第三次作业我直接放弃了自动测试模块,自己强测的bug也没被同学发现,可能是房间都在用自动测试的原因?
这种特殊情况不特意构造也难以发现问题,倒是房间内许多同学选择了化简去追求更多的性能分,但是往往化简就会产生bug
我这里建议化简后一定要进行回归测试,不然不能保证正确性的化简是毫无意义的。
我手动构造了两组样例,成功hack掉两个同学的两个bug。
- 其实从我个人来说,一个复杂样例WA,往往对应的一个简单样例也会WA,这种简单样例是可以轻易通过人脑来思考得到的,所以也没必要迷信自动化测试,但是对于复杂程序来说,自动化测试是测试其基本功能的利器。
四、关于重构
- 第三次作业重构我也是花了不少的时间来构思思路,刚好第三周实验课学习了工厂模式,我也就直接趁热打铁拿上用了,但是发现这个复杂字符简单套用工厂模式也是会出不少问题的,又结合自己在构造是遇到的问题和对象的设计,进行修改,得到了现在的构架(虽然还是一团乱麻)至少它能跑不是么哈哈哈
五、总结
不管怎么说 OO的第一单元结束了,我也开始从原来的面向过程的设计模式开始慢慢的转变到面向对象的设计模式了甚至我都不会写OS代码了,虽然挺肝,但是至少让我用一个月时间从没写过Java到写了上千行代码的一个突破,对我个人的提升也是非常大的,包括但不限于对编程能力的提升,还有测试思想和构造思想等方面,但是由于众所周知的原因,感觉这门课还是缺少工程或者开源项目中的那种协作精神,但这门课能做到这样已经非常不错了。之后的学习工作肯定还要面对更多挑战,我能从中拿到我之前没有的东西也就足够了。
最后感谢各位老师助教和大佬对我的指点和支持(@ZTY老师 @GYF助教 @Hangsbug @蓝头像 @胡歌滚 @笑死羊 @林雨桐 @prime21 @t123yh @bear @cjb @wpb @my @yzm @jyc @kongyou.........)