OO_第一单元总结
oo第一单元的基本任务是对输入的字符串进行求导操作,表达式的复杂度逐次增加。
- 第一次作业
第一次作业实现的功能很简单,同样初识面向对象,实现的也很简单,只是简单的用到了一些面向对象只是。三个类,PolyNomialDerivation负责输入的处理, PolyNomial类是项类,求导,符号化简,系数比较,toString都集中处理了,Constant类存放了一些固定的数据,如正则表达式等。
度量分析:
第一次使用度量分析,看到自己的main函数和打印函数的iv(G)和v(G)很高,这两部分使用了较多的if,else进行判断。
- 第二次作业
第二次作业增加了三角函数,自己在第二次作业中还是没有开窍,设计思路依然局限于第一次,没有想到过如何层次化设计,与第一次作业相比,第二次作业使用了HashMap来存放项,因此增加了一个HashMap类实现equals和hasCode方法。可能和第一次比唯一的进步就是从大正则处理整个表达式变为了因子,项的正则,其余和第一次基本相同。
度量分析:
第二次作业中,同样的,toString函数主函数以及项类的构造函数iv(G)和v(G)较高,这三部分也是因为判断使用了较多的if-else语句。而打印函数的ev(G)较高,可能是我在打印时,使用HashMap连续遍历了两次,使用了两次迭代器。
- 第三次作业
第三次作业的难度明显提高,出现了表达式因子,嵌套等情况。在第三次作业的思考过程中,一直在思考如何处理输入,并且如何将输入正确的求导并输出。最终受到指导书的启发,对表达式因子,嵌套因子和项建了类,然后对拆分到最后的普通整数因子,幂函数因子,三角函数因子建了一个类。接着递归对表达式进行拆分,直到拆成最简单的因子,求导也是如此。但遗憾的是,我依旧没有开窍,可能是对接口,继承等概念理解不是很深刻,也可能是重心放在了如何对表达式处理,如何求导上,(当然最主要的原因是是太蠢了没有深入的思考),因此最终没有实现层次化设计,仍然是最普通的每个类各自独立。
可以看到,第三次作业在复杂了很多的基础上依旧只使用了四个类,导致每个类实现的功能过多过杂,难以阅读难以更新难以维护,没有深刻理解继承接口的思想,更没有运用到作业中来,需要重新思考好好理解。
在进行括号匹配的方法中,定义了很多局部变量,使用了几个for循环和if-else语句,导致这个方法难以理解,容易出现错误。而两个求导函数,综合了很多求导,使得方法十分复杂。
- 互测
1、自己的BUG
在第二次作业中就出现了致命的BUG,根据项的符号来判断项最终的系数时,遇到负号系数乘-1,写成了等于-1。如此致命的BUG,弱测和中测竟然没有测出来!!!我竟然没有测出来!!!最终强测错了五个点,被Hack了十几次,这充分体现了自我测试发现问题的重要性,掉以轻心最后的结果是沉重的,不然总会在互测和强测阶段吃亏。
第三次作业中也出现了BUG,在去除最后结果的最外层括号时,由于判断失误,导致一些不匹配的括号被删去。虽然最后没有被强测发现,但是还是证明了,我(菜鸟)的程序,永远有BUG。
2、发现别人的BUG
第一次互测时,使用静态找BUG法,(其实就是阅读别人的代码),然后读到头痛只读了一两份,并且一度以为互测的意义就是读别人的代码来学习别人的长处。其实我觉得这个想法没错,但是在后两次作业中就无法实现了,因为代码过长,太浪费时间。于是就写了一个简单的脚本,然后将每个人的输出使用MATLAB的simplify(a-b),a和b分别是两个人的答案,一般情况下结果为0,当出现一个不是0的时候就有错误出现,当然不排除七个人犯了同一个错误。
但是我又发现了一个问题,我想不出能找到别人BUG的样例。根据互测的思想应该是思考哪里容易出现错误可能出现错误,构造相应的样例。但是我感觉自己很难构造出能发现别人BUG的样例,可能是我对易错点的把握度不够,这同样反应出我对自己代码的问题发现也同样困难,代码中容易存在很多问题自己却难以发现。
- 总结
总结自己第一单元的三次作业,首先没有从面向过程中转变过来。没有正确理解继承和接口,没有对代码实现一定的层次化设计。可以说是很失败的,但也学到了正则表达式,类,容器等面向对象的一些基本知识。后来从讨论区学长的分享知道了,继承主要解决数据的共享,而接口解决操作的共享,这两句话让我对继承和接口的区别瞬间有了很大的理解。
针对第三次作业,因为所有的因子都需要求导,都需要转变为String来打印,化简时都需要判断,因此完全可以定义一个Expression接口,定义toString,derivate,equals等方法来规范行为。输入的表达式可能拆分为项,项可以拆分为三角函数,常数等因子,针对项和每一种因子新建一个类,每个类都继承这个接口,实现借口中定义的方法。同时,在定义这样一个接口以后还有一个好处,可以方便同时管理所有的对象,可以将因子对象都声明为接口的引用类型。
希望自己在接下来的单元中,能熟练应用这些面向对象的基本知识,起码首先让自己的代码不再这么丑陋。