OO_多项式求导_单元总结

时间:2023-03-08 16:43:20

概述:

  面向对象第一单元的作业是三次难度依次递增的多项式求导。第一次作业是仅包含带符号整数和幂函数的多项式求导,例如:-1+xˆ233-xˆ06;第二次是在前面的基础上增加了三角函数的求导,例如:-1+xˆ233*xˆ06-sin(x)*3*cos(x);第三次是增加了嵌套函数的求导,例如:(-1+xˆ233)*sin(xˆ2)ˆ06-cos(sin(x))*3。经过三次的求导训练,我学会了正则表达式的用法、Java内大数运算、对象与类、继承与多态、异常捕获、利用checkstyle检查并规范自己的代码等。

一、基于度量分析自己的程序结构

1、类图

  三次作业难度递增,类图的结构复杂度递增。前两次作业的项以及项求出来的导数具有相同的格式,故整体可划分为从输入串中读取项、求项的导数两大块内容。第三次作业复杂一些,采用了边读项边求导的方法。

1.1 第一次作业类图

OO_多项式求导_单元总结

  第一次作业结构相对简单,共分了CalculateDerivatives(计算每个项的导数)和ExtractCoefAndIndex(提取出每个项的指数和系数)两个类。写这次作业的代码时,刚开始接触java,代码中有很大部分还是过程式程序的写法,而且类的定义也不是很合理。总的来说,第一次作业并没有写出一个面向对象式程序应有的框架,很失败。

1.2 第二次作业类图

OO_多项式求导_单元总结

  第二次作业分成了Term项类和Expression表达式类(其中包含Main函数),通过这次作业学会了重写hashcode和equals等,但是代码中有很大的冗余,主要是自己构思的时候没有考虑清楚。而且,这次的代码只能为这次的作业服务,可扩展几乎为零。一旦更改要求,代码可能就要全部重写。

1.3 第三次作业类图

OO_多项式求导_单元总结

  第三次作业中涉及嵌套,结构相对复杂。分为常数类、三角函数类(包含嵌套)、乘类、加类、幂函数类五个类,通过接口返回每个类中的因子的数值和求导结果,整个代码运行过程中相当于从上到下生成一棵树,然后从下到上返回值和导数。这次的代码相比较前两次,整体可扩展性强,结构清晰。但是,我是用String类型返回的值和导数,这就使得项中的一些特点被抹去了,很难合并同类项、做相关的优化。所以,这次作业只能保证正确性,可优化性几乎为零。

2、利用MetricsReloaded插件的度量结果

 根据博客https://www.cnblogs.com/panxuchen/p/8689287.html安装并使用了该插件,运行结果如下:

2.1第一次作业度量结果

OO_多项式求导_单元总结

2.2第二次作业度量结果

OO_多项式求导_单元总结

2.3第三次作业度量结果

OO_多项式求导_单元总结

  ev(G)基本复杂度是用来衡量程序非结构化程度的,数值越高意味着非结构化程度高,难以模块化和维护。

  Iv(G)模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。数值越高意味着耦合度越高。

  v(G)是用来衡量一个模块判定结构的复杂程度,数值越大说明程序代码可能质量低且难于测试和维护。

  根据以上三个值判断,我的程序的高内聚低耦合度很差。主要原因是我的代码中类之间的层次没有分清,各个类之间的独立性较强,相互调用的少,没有区分好过程式程序和面向对象式程序。之后的实验中,我应该在代码的框架构思上多花些时间。

二、分析自己程序的bug

第一次作业的bug,主要是没有处理1*x的情况,之后将输出字符串单独处理,把1*消除。

第二次作业的bug,是因为程序的鲁棒性差,没有判断是否hasnextline(),导致程序在没有输入的情况下调用了String.nextline()函数,报错。

第三次作业的bug,是因为加括号的问题。有些地方必须要加括号,否则在特定的情况下会出错,例如sin(x+x)应该写成sin((x+x))。

bug的存在主要是因为设计的时候没有考虑到整体性,没有想好细节就开始写代码,导致debug之路漫长。

三、分析自己发现别人程序bug所采用的策略bug

1、自己构造比较全面的测试样例

  在第一次作业中,正确的输入和错误的输入的种类相对较少,可以实现全覆盖的测试;第二次作业兼容了第一次作业,故可以用第一次的测试程序来测第二次的代码,之后将第一次的测试样例中的 x 换成 cos(x) 或 sin(x) 继续测试;第三次的作业情况较多,很难全部覆盖的测试,可以根据自己的代码特点,每个分支写一个测试样例,保证覆盖测试自己代码的全部分支。

2、与同学交流

多多查看讨论区,学习下大佬们的思路和方法,避免踩大佬们踩过的坑;可以和周围同学多多交流,相互找bug。

3、写代码的时候保持脑子清醒

要在大脑十分清醒的情况下写代码,不然会出现很多的眼高手低的笔误,增加了debug时间。

三、Applying Creational Pattern

结合三次作业的要求,如果重构,我选择用工厂模式。

将输入串分解成一个一个的因子,之后利用工厂模式建立一个一个的因子类,每类中单独求导并返回求导结果。

OO_多项式求导_单元总结

四、总结与反思

  这三次作业给我的经验教训是,一定要先学,然后再写,不然很容易造*。想好整体的思路之后再动笔写代码,不要急于求成,不然,会像我的第一次作业一样写出很多冗余的代码。