OO第一次博客总结

时间:2020-12-28 17:27:14

虽然早在开学之前就已耳闻过OO这门课的威力,也在寒假自学了一些java的语法,但在真正面对OO这样的工程训练时才发现寒假所学的那点语法简直不值一提,也深刻的感受到在这个过程中自己的提升确实很快,毕竟ddl是第一生产力。

 

第一次作业-一元多项式加减

 


 

1.程序结构分析

类图:

OO第一次博客总结

代码分析:

  OO第一次博客总结OO第一次博客总结

 

 OO第一次博客总结

 整体上来看,虽然本次作业用了一些面向对象的特性,比如多项式类和数对类,但从主类ComputePoly来看依然是个过程式的程序。最大的体现就是主类里有非常多的static全局变量和static函数,然后在main里依次调用。说白了,这就是一个伪过程式程序。

耦合度方面,可能是因为第一次作业比较简单,整体上的复杂度和耦合度都还可以,只有ComputePoly类的复杂度略高。

2.自己程序的bug

这个程序只有一个bug,却令我非常懊恼。这个bug的原因在于我正则表达式只能匹配两个项以上的多项式,导致我程序对于所有单项式输入都是直接判定为ERROR。因为这个小bug,我公测挂了6个测试点!!!所幸互测没有产生新的bug。在此也提醒各位同袍们,进行输入格式判定的正则表达式一定要仔细检查,不然一字之差就会导致公测6个点报错甚至更多。

出错的代码段:

String itemRex = "\\({1}[+-]?\\d{1,6},[+]?\\d{1,6}\\)";
String polyRex = "\\{((" + itemRex + "),){1,49}(" + itemRex + ")\\}";

改正后的代码段:

String itemRex = "\\({1}[+-]?\\d{1,6},[+]?\\d{1,6}\\)";
String polyRex = "\\{(" + itemRex + ")(," + itemRex + "){0,49}\\}";

3.别人程序的bug

我所拿到的程序没有使用正则表达式,而是非常复杂的if-else条件判断,连注释也没有。因此我并没有根据其代码结构来设计样例,而是按照分类树将分类树的每个分支都设置了一个样例(实际上在测试自己程序时已经写好了样例,只是忽略了单项式这一边界条件没查出自己的bug…)

该被测者虽然程序结构不是很好,可读性也不高,但是并没有被我查出来bug。

4.心得体会

1) 这次作业确实能起到速成java的作用,尤其是对于正则表达式的使用,配合实验可以很快熟练掌握。

2) 对于正则表达式爆栈问题,我采用的处理方法是对于多项式依次匹配,即每匹配到一个就把这个多项式从整个字符串中去除掉,再匹配剩下的,这样反复迭代就可以避免输入的整个字符串过长爆栈。看到之前的同学有提到这个问题,因此可能有些借鉴意义。

3) 实际上这次作业消除了一部分我对于OO课程的恐惧(可能是因为还没有做到多线程Orz 虽然因为一个小bug挂了6个点,但是我能在3天内通过自学速成一门语言并实现一个小功能,已经是很有成就感的一件事情了。(也可能是我比较菜,满足感的阈值比较低

4) 回头看这次程序的代码,还是过于偏向过程式程序,用到的新知识无非是正则和简单的类操作。后面的电梯明显比这次程序要好

 

第二次作业-单部傻瓜电梯


 

1.程序结构分析

类图:

OO第一次博客总结

代码分析:

  OO第一次博客总结

OO第一次博客总结

本次作业的类图完全是参考推荐设计,但是Floor类是个空类。虽然命名和推荐设计一样,但是推荐设计中Scheduler的一部分功能聚集在了Elevator中,这给我第三次作业造成了很大的困难。

这次作业的复杂度依然不错,但是用于运行的主类Run依然出现了红字(17),入口函数main的相关向量值也非常高。本以为会很冗余的Elevator类却还可以。

2.自己程序的bug

因为设计原因,我的程序在运行2的32次方-1的时间输入的请求时会timeout,挂了两个公测点,但是后来助教应该把这个问题解决了,不算bug。

互测阶段被发现了一个bug,是由于我在判断同质请求时未遍历当前所有待执行请求,而是只排查了队列的最后一位。这是写代码时的逻辑疏忽造成的,也说明了自己在测试时不够全面。

3.别人程序的bug

这次抽到了一个大佬的程序,不仅程序简洁,也确实没有bug。我采用的方法依然是按分支树测试。我仔细研读了一下,发现他是完全模拟电梯实际情况,包括各楼层的按钮,电梯内的按钮。我想这可能是老师一开始希望我们写的设计。

4.心得体会

1) 和计组一样,设计要先于实现,好的设计可以节约很多debug的时间。我花了很长时间思考本次作业的算法,在思考完成后很快便实现了主要的功能,后面又修复了一些bug。而之后的第三次作业由于是添加功能,我便没有做好设计,而是修修补补,直接造成了我程序可读性的大幅降低。

2) 由于每个人对作业的理解和设计都不一样,所以程序之间相差很大。但是老师布置的作业似乎是想让我们贴近“官方思路”。从第三次作业也可以看出,越贴近“官方思路”,实现起来越容易。我觉得这在某种程度上会限制我们思路的扩展性,但也可以引导我们,节约写程序的时间。

3) 我没有很好的使用Floor类,导致Elevator类内聚过高。

 

第三次作业-单部ALS电梯


 

1.程序结构分析

类图:

OO第一次博客总结

代码分析:

OO第一次博客总结

 

第二次作业设计思路与“官方思路”的偏离直接导致了第三次作业与“官方思路”越来越远。从类图中可以看到我在Elevator类中创建了太多的函数;还创建了三个请求队列;Scheduler的改动却寥寥无几。究其原因,在于我对第二次作业的理解不同。我认为Scheduler类是将当前时间的请求给Elevator类,从而Elevator有一个待执行的队列,剩下对于待执行请求的处理(包括哪些捎带,哪些同质)则由Elevator类完成。而我想其他同学的程序中,Elevator只是一个被操控的对象,Scheduler负责现在让Elevator往上还是往下,停还是走。

思路的差异带来的是设计上代码量分配的不同。本次作业我Elevator类的WMC(Weighted Method per Class)达到了惊人的69,说明复杂度极高。部分核心函数,如checkOnTheWay(对捎带请求的处理)的Cyclomatic Complexity Metric (v(G))和Module Design Complexity Metric (iv(G)) 极高,一方面可能是代码不够精简,一方面也可能是因为由于设计原因,对于捎带逻辑的处理就是这么复杂。

2.自己程序的bug

本次程序公测和互测均无bug。

3.别人程序的bug

由于本次作业分支树太多,我采取了和前两次作业不同的测试方式。除了设计了几个在自己的测试中体现出来的易错bug样例以外,其余我采用了脚本生成的方法批量测试。最后成功找到了两个bug,一个是捎带请求和主请求输出顺序错乱,一个是同质请求和捎带请求判定错乱。

需要特别指出的是,我认为作业指导上所述“根据被测程序代码结构来设计测试用例”很多时候并不可取,同学们更多的是采用黑盒测试的方法。就拿我拿的代码来说,总行数1000行,注释寥寥无几,变量名也不规范,真要读下来太过艰难。

4.心得体会

1) 像这种往代码上添加功能的程序也要提前做好设计,不要一点点往上加功能,然后不断测出bug不断改。本次作业我这样干了,导致代码可读性极差!核心类的复杂度极高!经常需要在一个类的开头几行加几个判断,然后又在最后几行加几行代码。

2) 注释非常重要,变量名命名要有意义。本工程小白首次出现:周一晚上写的代码,周二白天居然就看不懂了 这一现象。本来说写完后补注释,后来也懒了没加,让我现在再回头看第三次作业的代码,估计又看不懂了(多线程怎么办啊Orz

3) 功能过于集中,导致可读性很差,也没有进一步发挥面向对象的功力。看过几个大佬的博客,他们的类图中有若干个类,相对而言复杂度就低一些,而我和上一次作业相比几乎没有增加新的类,导致Elevator类代码行数从100不到飙升至300(正如吴老师课上所说,一个类代码量很高,已经说明出现了很大的问题)

总结

整体来看我对自己前3次作业的情况还算满意,前两次作业各有一个bug,第三次作业没有bug。但是设计上仍然有待改进,无论是代码规范还是设计细节等都和大佬们相去甚远。希望接下来自己能再接再厉,争取从这门课程中收获满满。