写在前面
在接触OO课程之前,自己是完全没有学习过java语言的,因此作为一名初的不能再初的初学者,无论是在哪方面都会有许多茫然,但是我相信通过一次次认真的完成OO作业,我对面向对象的理解应该会渐渐的深入,就写在博客上记录下我的点滴的收获。下面是我对前三次作业的分析与体会。
作业分析
(一)第一次作业
类图如下:

度量分析如下:

代码分析:
因为第一次作业对面向对象编程几乎没有概念,因此就当是按照C程序那样编写,现在一看这就是完全的面向过程的编程方法。在一个class里面定义了完成该程序需要的几个方法,比如判断合法性、提取项、计算、简化等,然后在main函数中顺着自己(读取->判断->拆分->求导->合并同类项)的思路编写。而通过上图的方法的度量可以看出,ev(G)基本复杂度普遍比较高,说明第一次程序的结构化程度比较低,这样增大了程序的理解难度,并且也难以进行代码维护。
这次作业我优化方式是采用的每计算出一个项来,就将它的系数与指数用特殊字符连成一个字符串然后压入一个ArrayList数组中,然后在压入数据时,遍历之前已经压入的,如果指数相同就进行合并,最后输出总的表达式。但是存在比较大的一点疏忽是类似(a - b) 是要比(-b + a) 有效长度短一些的,由于这一点没考虑到,因此影响到了自己的性能分。
(二)第二次作业
类图如下:

度量分析如下:

代码分析:
这次作业我是采用三元组的方式完成的,即a * x^b * sin(x) ^ c * cos(x) ^d。由上图可以看到这次作业分了4个类,其中Work类即主程序执行main函数,Ifvalue负责对输入进来的表达式进行合法性判断与拆分,Hanterm类进行项的处理与简化,在Dercom类中进行运算。而我这次的优化与第一次几乎一样,只不过这次是变为往ArrayList数组中压入四个参数组成的字符串,但是处理方式还是没有变化。
值得一提的是,虽然这次勉勉强强的为程序分了class,但是细看的话还是有很大部分是面向过程的。感觉写的时候就是本着要用哪些类完成哪些过程、实现哪些结果的目的而创建的类。这样还是有一些面向过程的,比较明显的是通过上面的类图可以发现每个类里面的参数几乎只是为了这次作业而做的,也就是说没有一定的独立性,当单独拿出来一个时,可应用性就不大了,并不能实现像java自定义的那些类(比如String)一样即能实现一些特定的功能,又能保证适当的独立性。用比较通俗的语言来说就是我感觉这些类是从这个程序的一个类里面拆分出来的方法组成的集合吧,我认为这主要是我对类的理解还没有多么深入而导致的,总归是需要慢慢探索学习的。
(三)第三次作业
类图如下:

度量分析如下:


代码分析:
这次作业我的主要思路是先假想输入的表达式为一个合法的字符串,然后按照一定的规则以'+'分隔出各个项,然后再以'*'分隔出各个因子,如果遇到括号,那么久一直记录直到遇到与其相对应的右括号才结束,然后将所有因子依次用正则表达式匹配,共有五种形式(常数, x, sin, cos, (.+)),匹配到哪个格式就新建相应的类,然后在类里面进行相应的简化与计算;如果这五种格式都没有匹配到的话,那就进入异常处理的类,直接输出WF。
我认为第三次作业才算是真正一次我对类的一种比较正确的使用方法的一次尝试,在这次作业里我分别建立了term类与factor类进行相应的处理,同时建立了x,sin等不同形式因子的类,针对不同的类有不同的处理方式。但是让我感到遗憾的是本来在设计中设计的借口与继承在真正编写时却没有用到,所以我在编写程序时还是有一定量的代码复用的。这是我设计上的失误,没有完全设计好应该怎样去办。
BUG分析
前面两次作业因为思维量并不是很大,所以我在想好思路后尽可能的考虑输入可能出现的各种情况,因此在强测与互测中都没有被狼到。但是这应该并不是代表我的程序就没有Bug了,记得老师上课还说过我们的程序一定有或多或少的Bug呢~但是刚刚上面提到的一个优化的问题是我直到看到第二次强测结果后才意识到的,所有关于(a - b)与(-b + a)的问题我都没有考虑到,因此前两次作业虽然我在自己的能力范围内都尽力去把优化做好,但一直没有拿到比较高的性能分。
然而第三次作业我是的的确确出现了两个比较致命的Bug。一个是我在对括号内的因子求导时直接提取出了里面的内容,并没有考虑到括号外面的符号的问题,换句话说,只要评测中出现了-()之类的内容,我输出的结果应该就是错误的。第二点是我在对项进行拆分的时候没有考虑到式子中kennel出现类似 ^ +2 、 * +2 这样的部分,因此我对项的拆分时会将这部分也拆分,这就导致了本来正确的输入被被我硬生生的搞成WF。
我觉得导致自己出现这些bug的原因主要有两点。一点是由于一开始好长时间都对第三次作业不知道该如何去处理,直到周一晚上之前我一直处于苦恼的过程中,当时只是打算把表达式的项拆分掉,这就导致了对所出现的情况没有考虑全,因此就写出了Bug。第二点是我之前写代码总是想先把思路完全给弄通了然后在去整体的额写,这就会导致我可能在设计的时候会对哪几方面设计的不完全,因此在写的时候也就没有考虑到,由此又回写出Bug。
我在hack其他同学时不论是使用脚本,还是对同学依次测试,我都会先对一些可能的边界情况进行检测,就比如输入只有一个因子,结果化简完之后因子全是0等情况,因为我觉得一方面有可能同学们在编写代码的时候就默认了这是个有许多项的多项式,另一方面有可能同学们在优化时会有些放松,就有时难以考虑到全是0的情况,就会导致没有输出结果了。
体会与感受
总之我觉得这第一单元的三次作业一定程度上应该只能算是OO课程的入门考试吧,虽然自己在写的时候会遇到许多困难,但是也都是慢慢被虐过来了。。而在这三次训练中,我从一开始的不知道什么是方法,为什么要分class到现在已经对class、对接口、对继承、对抽象类渐渐有了一些理解了,我相信欠缺的许多知识与相关方面的理解总会通过后面的练习而慢慢去理解与运用的,我们同学就把学习OO当成是一种成长呀。