OO第一单元总结
第一次作业
思路与反思
在第一次作业中目标是实现幂函数的求导,所以我创建了PowFun类存储指数,Item类额外存储系数,Func类存储表达式,实现了求导以及优化输出方法,RegularExpression类用于获取Item,主类先处理了空白符以及运算符,使得Item的获取更加简便。此次作业将类都作为Main的子类来使用了,耦合很严重,主要思路也是面向过程,将存储的数据保存在对象中,代码中分支语句繁杂,可读性差。起初在重写equals上出现了很多错误,导致之后bug的产生主要在于合并同类项时对象引用与克隆的不同。在处理空白符和运算符的时候使用了太多分支,容易漏判错判,并且修改时可能产生新的bug,对正则的使用不是很熟悉。
UML类图
度量分析
耦合度
第二次作业
思路与反思
第二次作业额外增加了三角函数和输入格式错误判断,增加了函数的类别,同时将每个Item表示为系数、sin(x)的指数、cos(x)的指数、x的指数组成的四元数组,这样使得求导与合并同类项十分简便,每次求导可以产生3个项,每个项的四个元素分别由原项的元素表示,合并时在容器中寻找后三个元素相同的项即可,此处同样存在重写的问题,起初我使用的HashMap而不是ArrayList,还需要重写hashcode,此处的错误导致产生了一些合并同类项的bug,由于代码可扩展性很差,在添加函数的时候需要在多处方法修改,而且代码复制量大,方法东一个西一个,无法简便地管理。判断WF时由于采用了判错的方法,有很多漏判错判的情况,虽然过了修复后过了强测,但给代码重构存留了很大隐患。第二次作业在第一次作业的基础上增加了三角函数,同样在创建时没有改变结构,在主类里创建了所有的类,耦合严重,导致下一次作业重构时要面对很大的困难。
UML类图
度量分析
耦合度
第三次作业
思路与反思
第三次作业增加了因子的嵌套,主要是sin()中可以有除x外的因子,另外表达式加上左右括号可以成为表达式因子,在第二次作业的基础上,幸好能够沿用的代码有1%,在花费很长时间学习面向对象思想与思考代码结构之后,在表达式处理方面,想要脱离之前WF完全判错的方法,更改为判对的方法,在处理一些空白符与运算符后,在每次正则匹配到表达式Poly、项Item、因子Factor后将匹配结果删去,根据完全修改后是否有多余字符来判断WF。在求导输出方面,想要让所有函数连接一个求导接口,分别实现各自的求导方法,将原表达式解析成四种运算符(+,-,*,嵌套)与函数组成的树结构,每种运算创建一个类,来实现复合函数求导。但是在处理嵌套递归里对表达式、项、因子的匹配时由于正则表达式以及递归条件的错误导致无法跳出递归,最后这次重构没有得到好的结果。
程序bug分析
第一次作业在互测中产生了运算符化简导致的bug(+-得+改为+-得-即可),核心问题在于首先处理表达式时,多个+-不能随意简化,应该根据正则匹配来决定运算符的存在是否格式正确比较合理。
第二次作业产生了WF漏判错判的bug,求导中BigInteger的求相反数使用不当导致报错,以及求导结果的三项四元组中正负写错的细节问题。
第三次bug本身是一个作业
寻找bug的策略
首先测了自己出错过的数据,在看过其他成员的代码后,(与屋内其他超长数据不同)构造的数据都十分简单,有针对性地hack私以为有误之处。之后再避免同质的同时构造一些复杂或极简的数据来盲目地测试。
心得体会
在pre后第一次系统性地完成这样一层层迭代的作业,过程十分坎坷,在钦佩其他优秀的同学的代码的同时深深意识到了自己的不足。不过自己在学习编程很吃力时也有向未知领域的更多尝试,算是对自己的一点慰藉。通过这次作业,初步形成了从面向过程到面向对象的思维模式,虽然在实现上仍有困难,但对比刚接触oo时的茫然无措还是有一点进步。
讨论区的很多解答让我感到醍醐灌顶,一些困扰自己许久的问题在讨论区找到了答案,在研讨课上也学习到了很多其他同学的知识分享。同时在构建代码时要学会考虑到代码的可扩展性,否则重构约等于死亡。
第一单元既有难过也有收获,希望自己的心态能越来越好。