BUAA_OO_2021 第一单元总结

BUAA_OO_2021 第一单元总结

一、第一次作业

1、总体架构分析

  第一次作业中一共包含了三个类MainclassExpressionTerm。其中Mainclass类使用控制台输入的字符串构造Expression对象,调用Expression中的求导方法并输出。Term类是存储单项式系数和指数的类,实现了单项式的求导方法以及重写toString方法。Expression类先对输入字符串进行化简处理,然后拆分构造多个单项式,使用Map进行存储,方便同指数单项式合并。

程序类图:

2、基于度量对程序结构的分析

类复杂度:

 

方法复杂度:

 

  从上面的表格中我们能够发现,程序的复杂度问题主要体现在Expression类的构造算法当中,经过检查后发现这部分的程序结构确实过于复杂。字符串处理以及许许多多的循环和判断语句使得程序变得十分复杂。改进方法我认为可以将字符串处理方法单独创建一个类,使得各个类的程序之间分工明确。

  当然这次作业虽然有缺点,但不可否认的是,是我三次作业的代码中写的最好的,使用Map进行了化简工作合并同类项,虽然一些细节地方例如正项提前、x^2的化简没有考虑到,但是其他化简情况都考虑到了,希望今后写作业的时候可以拿出这次作业精益求精的劲头来。

3、分析其他同学bug的方法

  根据自己在第一次作业中犯下的错误,读其他同学的代码,手动hack。发现一位同学犯过和我一样没有处理多个加减号的失误成功hack一人。

二、第二次作业

1、总体架构分析

  第二次作业我采用的方式是构建表达式树的方法,处理好输入字符串之后按照运算符号将表达式建成树,对树的叶子节点进行求导,按照表达式树逆向求出导函数。但是实现过程中由于大量面向过程,导致最后程序bug过多,致使实验失败,因此我改变了算法并重写,直接进行了第三次作业。

2、失败的经验教训

  此次作业出现的最大的问题是面向过程编程,其实偷偷浏览其他同学的博客的过程中我发现有些同学处理这个问题的想法和我第二次作业中的架构的想法非常相似,但是其他同学做出来的很明显能够感受到面向对象的特点,而我则是面向过程。并且由于个人不好的习惯作业拖到了周六晚上才开始写,时间不够充裕导致及时熬夜了也没能成功完成这次作业。另外一个巨大的败笔便是没有提前进行架构,写代码时想一行写一行,导致实现过程中bug非常多,多到最后不得不放弃所有的代码,并且代码之间的耦合程度也非常高。

三、第三次作业

1、总体架构分析

  第三次作业中主要分为三个部分,首先是表达式部分,主要类Expression,作用是根据输入的字符串构建表达式类,并将表达式中的项拆开。第二是项部分,主要类Term,作用是将类拆分为函数因子。第三部分是函数因子部分,主要类PowerCircularExfunction均继承Function类,分别代表幂函数因子三角函数因子以及表达式因子。采用工厂模式管理这三个类。为满足第三次作业的复合函数求导规则,Circular中包含一个Function对象,表示三角函数括号中的因子。然后上述类统一实现了一个求导接口Diff,通过互相调用Diff方法实现求导操作。

程序类图:

 

2、基于度量对程序结构的分析

类复杂度:

 

方法复杂度:

Circular类:

 

Clean类:

 

Exfunction类:

 

Expression类:

 

Function类:

 

Power类:

Term类:

 

  从上面的表格中我们可以很明显地发现程序的复杂度问题主要出现在了Circular类、Clean类、以及FunctionFuctory这个工厂类,Circular类中重写的toString方法复杂度过高,究其原因是设计上面出现了一些问题,我再Circular方法中设计了求导标记,将求导和未求导的toString方法写在了一起,使得复杂度超标。Clean类除了进行字符串整理工作还有大量的判断语句进行判断Wrong format,使得复杂度很高,我认为可以采用单个字符读入判断格式和整理分开而不是将判断格式和整理字符串混合在一起的方法降低复杂度。工厂类中也混杂了一些Clean类中无法判断的Wrong format问题的处理,应该将其分离。

  这次作业的有点在于开始有面向对象的特点了,在实现第二次作业向第三次作业的迭代过程中由于面向对象的特点并没有进行很多的工作,处理起来十分舒适。但没有进行化简工作还是有些懈怠,希望下次努力。

3、bug出现的原因及其修复

  第三次作业中强测bug出现都是Wrong format判断错误,集中在三角函数的异常判断上,首先是括号不匹配的问题,通过在程序中检测括号匹配成功解决;其次是三角函数中加减号带常数这种表达式因子没有识别出来,通过匹配正则表达式将这种问题排除;还有便是sin()中不含任何因子只有括号的情况,通过消去括号检测最内层括号是否为空解决。总结原因是我采用的修复Wrong format的方法似乎是面向评测机编程,只检测评测机中可能会出先的错误格式问题,我认为应该在字符串输入过程中就按照统一格式检测是否有格式错误,解决方案还在思考。

  互测过程中,由于大家的代码都比较长,读代码检测bug的方式很笨重,最终没能hack到任何一个人,正在学习自动评测机的制作中,希望下一单元的作业能够通过使用自动评测机结合读代码的方式hack其他人。

  并且此次作业虽然成功完成,但是由于时间关系,代码的性能过于粗糙,希望自己有时间时能够思考一下如何提升性能分数,立好flag

四、重构经历总结

  我第一次、第二次的作业部分地方有较强的面向过程的特征,第一次作业较为简单,能够通过测试点并且拿到一个不错的成绩,但是第二次作业加入sin、cos以及嵌套的规则后整个问题变得复杂了很多,虽然进行了重写,但仍然没有意识到自己代码大量面向过程特点的我失败了,但也让我能够吸取这种经验教训。第三次作业中我对所有的代码进行了重写,每写一个类都尽可能的提醒自己要面向对象,虽然实现过程中还是出现了面向过程,但整体好了许多。在没有经过第二个实验测试的情况下,在第三次作业迭代时bug数量明显的减少了。着实让我感受到了面向对象的魅力。

  总结一下最重要的经验是:重写、重构一定要尽早做!!!血的教训!!!

五、心得体会

  总得来说,这一单元的作业帮助我了解到了面向对象编程与面向过程编程的区分,从前对两者的区分不是十分的明显,代码往往是面向过程的。在经历过第二次作业的失败之后,深刻地认识到了面向过程编程的缺点。

  OO课程对我来说难度有点大,第二次作业通宵一整天的时间都没有写完,确实有让我产生极大的挫败感,经过反思之后,在舍友的帮助之下,我意识到了代码架构的重要性,代码无脑的堆砌只会使得问题的解决愈发困难。

  同时自己在这一单元的学习当中也收获了许多新的知识:正则表达式、工厂模式、深浅拷贝,也带领我打开了版本管理的大门,学会了一些git的简单操作。我也开始注意到了一些自己代码风格的问题。

  期待在下一单元的作业中,能够学习到更多的新知识,能够更加得心应手,也希望自己能够跟上课程的进度,切实提高自己写代码的能力。另外,不够再继续懒惰下去了,要尽可能往前赶作业,防止写作业过程中出现无法处理的意外。

posted @ 2021-03-30 13:30  xiaominga  阅读(61)  评论(1编辑  收藏  举报