Summary of OO Unit1

本单元共有三次作业,分别为:

HW1:实现对仅包含简单幂函数的多项式的导函数求解。

HW2:实现对包含简单幂函数和简单三角函数的多项式的导函数求解。

HW3:实现对包含简单幂函数、简单三角函数、复合函数的多项式的导函数求解。

一、code analysis

先回顾一下三次作业的UML类图和Complexity metrics。

HW1

Summary of OO Unit1_第1张图片

HW2

Summary of OO Unit1_第2张图片

HW3

Summary of OO Unit1_第3张图片

HW1

class OCavg WMC
Poly \(\color{red}{5.67}\) 17
Term 2.00 10
MainClass 1.00 1
Total 28
Average 3.11 9.33

HW2

class OCavg WMC
Poly \(\color{red}{4.75}\) 19
Term \(\color{red}{3.73}\) \(\color{red}{56}\)
TypeX 2.25 9
TypeSinx 1.75 7
TypeCosx 1.75 7
Regex 1.00 9
MainClass 1.00 1
Total 108
Average 2.63 15.43

HW3

class OCavg WMC
Poly \(\color{red}{5.42}\) \(\color{red}{65}\)
Term \(\color{red}{4.64}\) \(\color{red}{65}\)
TypeX 2.20 11
TypeSinx 2.20 11
TypeCosx 2.20 11
Regex 1.00 14
MainClass 1.00 1
Total 178
Average 3.18 25.43

可以看到,三次作业下来,代码的耦合度基本处于直线增长的情况,程序变得越来越臃肿。究其原因,是自己不愿试错和探索,始终没有尝试使用低耦合的设计模式,如工厂模式,而是把很多面向过程的思路在三周内从头贯彻到尾。

HW1中,要实现的功能不多,程序勉强还算能看。

自HW2起,复杂度和耦合度似乎踏上了不归路。HW2是我的第一次代码重构,在Poly中用大正则取出各项后创建Term对象保存,进一步取出项中各因子的组成要素后再存入对应Type进行管理,最后Poly-Term-Type调用求导。从类中的方法可以看出,Poly与Term扮演了过分多的角色,尤其是后者几乎把本该属于Poly的化简功能、因子类的解析功能也都包办了,非常难以管理

HW2虽然混乱不堪,但还算实现了预期目标,即求导+化简,而HW3终于让我吃到了糟糕的架构设计带来的苦头。如果沿用HW2的思路,可基本实现表达式树的构建,经过上一次强测和互测的bug修复,求导的正确性也不会有问题,但是难以进行优化。沿用之后,为了实现递归调用求导,因子类只能选择链表来管理嵌套表达式,这样一来,先前通过比对因子的“全名”进行输入输出化简的方法难以实现,除非冒着TLE的风险,先把链表遍历化简一遍。

这时候,其实应该立即重构,把一切的起点,项的读入,彻底地换个血,一上来就将其化简,再交给Term,但是我却不想因此改变已经没有疏漏的求导方法,最终决定不再重构,放弃了性能分。

二、 bug analysis

HW1:输出时把求导前的系数当成求导后的系数,导致甚至没进入互测。

HW2:获取因子过程指数为0时漏取、求导后因子系数为1时化简错误、化简输出时多输出*号。

HW3:多冗余括号时的TLE。

bug虽多,但是最能说明问题的来自HW2。其余的bug尚可归因于偶然性以及不属于本课程重点的算法问题,但HW2的bug有很大的必然性。通过分析其bug所处的类方法可以看出,它们的产生根源于Term类过于臃肿,功能太多,难以管理。“集大成者”Term几乎与除读入外的所有工作都有关系,处理的数据之复杂可想而知。把多个包含大量特判的方法集于一身,不出bug才令人意外。

三、hack strategy

1.理解程序。

2.按照程序实现流程定位各部分的核心代码。

3.手动构造数据测试各部分边界情况,发现bug时尝试修复,再重复进行步骤3直到完成所有部分。

4.借助自动机生成数据进行多组测试。

四、对重构的思考

在后两次作业中,更好的思路应该是将创建项、创建因子、求导等行为抽象出来,引入更多的类。采用抽象工厂模式,为这些类提供不同的工厂,从而实现解耦,分而治之,如此程序才更具有层次感,方便管理和扩展。

五、对比和心得体会

善用一些设计模式才能够为程序带来层次感和组织感,实现易维护、易扩展、易复用、灵活性好的特点。

从下一单元起,希望自己能够学会抽象,从更贴近问题本质的角度设计结构;不仅仅追求正确,要大胆尝试不同的设计思路,把学会更好地设计程序作为学习本课程的真正目标。

你可能感兴趣的:(Summary of OO Unit1)