首先要吐槽一下,由于某些众所周知的原因,Idea的插件一直装不上,直到今天找到了一个能用的梯子才安装完插件。安装插件比写总结花的时间多太多了。
OO第一次作业可以说是让我一脸懵逼,毕竟在这之前从没有接触过java语言。语法什么的到还是小事,毕竟对于编程语言来说,学会了一种的语法,学习另一种也是不难的。主要的还是面向对象的思维,因为之前一直在写面向过程的代码,对面向对象未曾涉猎,外加老师课上特意强调不允许使用面向过程的思维写这次的作业,因此花了不少的时间在学习究竟什么是面向对象。即使如此,开始写代码的时候依旧还是对此感到模糊,但时间不等人,只好带着半知半解的面向对象思维进行工作。
第一次作业倒也不是特别难,毕竟指导书中已经给了使用正则表达式的提示。一开始写的时候,对输入字符串进行匹配的正则表达式写了长长的一行,是对整个字符串进行的完全匹配。当时写的时候只是感觉很长,并不觉得会出现什么错误,直到室友构造了一个合法范围内最长的字符串后,程序成功崩溃。当时还觉得奇怪,明明已经catch了Exception,为什么程序还是会crash呢?后来谷歌发现原来这是爆栈,属于Error类型,而不属于Exception。之后便改进了一下正则匹配的方式,从匹配整个字符串变成了将其中符合要求的多项式提取出来,最后拼接在一起与原输入字符串进行对比。这样分割之后便不再爆栈了。
因为第一次作业就只有两个类,类图就不贴了,下图是对复杂度的分析。
因为第一次作业代码量并不是很多,加之我将其分成了两个类多个方法,因此每个方法的复杂度并不高,这也是我这三次作业的复杂度分析中唯一一次没有标红部分的(叹气)。
OO第二次作业就不一样了,虽然第二次作业需要写的电梯一点也不符合现实情况,但是实现起来还是有点困难的。不过,还好指导书给了一些提示,要求我们必须实现五个类,由此可以大致对整个程序进行规划。类图及复杂度分析如下图所示:
可以看出我的Schedule类空空荡荡的,只有一个方法。其实我可以将判断同质从Schedule类的Run_elevator方法中分离出来单独作为一个方法的,正因为没有分离,为第三次作业埋下了后患,这点之后再进行分析。对于Request类的构造方法,这个方法对传入的字符串进行了合法性检测,但整体上也就只有两重if语句嵌套,3个分支,不知道为什么圈复杂度会高。Elevator类的两个update方法,当时写的时候还没发现,现在分析之后重新看了一遍,发现这两个方法大部分都是相同的,只有一些相对于楼层指令和电梯指令的差异,完全可以将这些相同部分分离出来作为一个新的方法被这两个方法调用。
第三次作业是在第二次作业的基础上使电梯支持捎带功能,而且输出的格式也发生了相应的变化。输出这一块儿也是搞得我很烦躁,因为我是调度一条指令便删除一条指令,为了使其能按输入顺序输出,我不得不开了几个数组专门存放指令的编号以用于输出。而且,这次要求新的Scheduler类必须继承原有的Scheduler类,这让我很绝望啊,毕竟我第二次作业的Schedule只有一个方法,这和重新写一个类有什么区别呢?但也不得不吞下这枚苦果。
类图和复杂度分析如下图:
由于方法比较多,便只贴了复杂度高的几个方法进行分析。像Elevator类中的release方法和releaseAll方法,这两个方法之间和之内还有很多重复语句,如果能提取出来单独作为一个方法就应该可以大幅降低复杂度了。Scheduler类的be_taken_ER和be_taken_FR方法,Elevator类的两个update方法同理。写的时候没有规划好,写完之后又懒得改,或许这就是原因吧。
在测试自己的代码的时候,除了时间方面(开关门)的小问题之外,还发现了一些关于if语句需要警醒的地方,那就是能else if 的地方千万不要图省事用else,万一哪一点没有考虑到基本上就可以愉快的打出GG了(此处@某人)。我的代码一开始不输入其他语句直接输入RUN之后,会经过两个else分支输出(FR,1,DOWN,0)/(1,STILL,0.0),改正这个bug之后我就又将代码中所有的条件分支语句都检查了一遍,能将else改为else if 的部分全部进行了修改,不怕一万就怕万一嘛。
对于bug测试这一方面,自己的三次作业倒是没有在公测和互测中被发现bug,自己测别人代码时也只有第三次作业检查到了别人的bug。不过虽然测出了他的代码的几个bug,但他的代码写的总行数确实比我少很多,要说缺点便是把所有的类写在了一个文件里面,浏览的时候十分不方便。
测试自己代码和测试他人代码不一样。首先自己的代码是自己写的,是把自己认为正确的部分写了上去,因此除非是某个时间段写的时候真的脑子进水了,否则通过阅读自己的代码是不太容易容易发现逻辑上的错误的。这时候就需要样例的火力覆盖了,之前是寝室里四个人构造样例然后分享,而现在有了buggy oo这个网站(此处表示感谢),用上面质量不错的样例测试自己的代码也可以很快的找出自己代码的bug。
而测试他人的代码,就不仅仅需要样例测试了,也需要大致浏览一下他人的设计思路,不仅仅是为了找出bug,也是为了学习,正所谓“三人行则必有我师焉”。就比如我测到的第二次作业,对方便用了Queue和Vector这两种数据结构,写的代码非常简练,也没有任何的bug,让我吸收了一波养分。
最后,进行一波总结吧。
指导书、issue、客服群的所有信息都要仔细阅读,万一漏掉了某些重要的点就悔之莫及了(说到这我就不得不吐槽一下了,感觉OO的这方面没有计组做得好)。
此外便是readme的书写,这点非常重要,千万千万别辛辛苦苦写完了,结果因为readme里面一些细节没有写好被扣了分。
还有就是规划要做好,不要写到一半了发现“诶?我这里似乎还需要再加一个什么什么判断什么什么”,出现这种情况就可能会导致代码臃肿了。