OO前三次作业阶段小结

一、写在前面:

  早在大一的时候,作为萌新的我就多多少少听说过面向对象这门课程的威名,如今终于算是近距离感受到了它的“魅力”。前三次的作业应该还只能算作是这门课程给予我们的小小的试炼,不过已经让我这个之前不曾写过Java,不曾面向对象的菜鸡“瑟瑟发抖”了。三周以来,也算是渐渐熟悉了OO课的节奏,从“熟练”地面向过程开始入门面向对象。期间的血与泪,走过的弯路,揪出的bug,体会到的些许心得,就让我趁着总结的机会,在这里一同诉说吧!

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

第一次作业:

  流程图如下:

  

 

  第一次作业的内容是实现多项式的加减计算,也是我对面向对象Java程序的第一次试水。不得不承认,带着一身“面向过程”的本领,重新进行面向对象的架构确实极具挑战。基于“精简main函数,做事靠对象”的基本原则,在我最终的架构中,Str类对象进行了对输入的判断,处理与存储,Poly存储单个多项式及属性,ComputePoly类实现的则是对所有Poly对象的运算以及输出,整个流程一气呵成……用“一气呵成”貌似不太对劲,因为貌似这种对象“轮番上阵”的操作还是没有摆脱面向过程的影子,有待进一步改进。

  类图:

  

  刚刚生成出这个类图的时候,我并没有从这一大堆英文中找出相关的度量信息。不过我很快“敏锐”地在一片蓝色英文中锁定了两个飘红的行。

  高清重置.jpg:

  

  于是到网上搜索了一下相关的含义:

  第一行,圈复杂度(Cyclomatic Complexity)度量,圈复杂度“用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,即合理的预防错误所需测试的最少路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护,根据经验,程序的可能错误和高的圈复杂度有着很大关系”。

  第二行,块嵌套深度(Nested block depth)度量,看到这个名字也大概可以理解它的含义,这里显示的是嵌套的深度,若是循环套循环套循环…可以想见的是这个参数就会不断飙升了吧。

       然后就能很明显的发现,本次作业中用于读入判断的Judge过于复杂了!

       我在judge方法中使用的是状态机的方式,因为这种方法能够准确判断出当前应当进行的读入于是对错误输入进行精准的发现。缺点当然也很明显,它太长了,所以太容易出错了,改起来太麻烦了。第一次作业的指导书提出了使用正则表达式的建议,不过鉴于使用正则表达式存在爆栈的风险,所以我舍弃了这种方式。当然是后来才知道存在着try-catch这种方法,可以避免掉程序的crash。然后我意识到,自己走了弯路orz。

第二次作业:

  流程图如下:

  

  第二次作业实现的是一步“傻瓜电梯”,不撞南墙不回头的那种“愣头青”。江湖(6系)人也称它为“智商度量器”,因为貌似我比“傻瓜”电梯还呆了那么一些。从零开始进行五个功能类的架构,再把它们联动起来,真的是不简单!读指导书,看讨论区,进行顶层设计大概就用了有一天多的时间。当我算是想明白的时候,时间已经到了周一的晚上,顿觉这次作业自己要凉凉。不过好在写代码的时候行云流水,顺利完成。这次“设计一整天,代码两小时”的奇特经历也让我体会到了码代码前进行构思与顶层设计的力量。整体架构和基本功能同PPT中所述,这里不再赘述。

  类图总览:

  

  类图节选:

  

  本次代码的一点小问题出现在圈复杂度上,具体来说就是进行了读入操作的main函数过于复杂。很可惜没有把“精简main”函数的理念进行到底,使得读入的流程太过复杂,也是本次作业中一个小小的遗憾了吧。

第三次作业:

  流程图如下:

  

  

  第三次作业实现的是ALS,增加了捎带功能的电梯。结构和指导书的要求基本一致,使用了schedule_ALS继承了原schedule方法,并且进行了接口的尝试。基于我第二次作业对构思作用的认识,我较早地读完了指导书,理解清楚了捎带的规律。发现,嗯,只需要增加一个捎带的功能就基本没问题了!然后周一晚上开开心心地开始编程,决定“编完这段儿我就上床睡觉”,于是flag立下之后,我就发现了事情没有想象地那么简单,结合处理同质请求的要求,捎带逻辑实现起来异常的复杂。进行了长达200余行的处理逻辑,最后终于在周二晚实现了正常运行,然而这也仅仅是噩梦的开始。因为,bug是真的多。代码越长,越容易在其中出现bug,这句活永远是真理,再加上一些认识上的错误,debug最终占用了不少时间。加上过程的仓促,debug的过程就像是在源代码上“打补丁”,拆了东墙补西墙,最终在增加了100行左右的条件下解决了bug。

  当然这样的代码是有待进一步精简的,时间原因未能如愿,可能在接下来的作业中我还会吃到逻辑复杂的苦果,类图飙红也是可以预见的:

  

  高清重置:

  

  由图可见,除去第二次作业中已经出现的main函数实现读入复杂的情况外,实现ALS调度功能的command函数逻辑显然过于复杂,有待精简。

三、自己程序的bug

  拜爆肝敲码和疯狂测试debug所赐,不出意外的话这三次作业中没有出现bug,这也让我疲惫的心灵得到了些许安慰。不过完成这三次作业的过程确实暴露出了不少问题,上面的分析也有详细提到,这里不再赘述。

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

  在我看来,对别人的代码进(hu)行(xiang)测(shang)试(hai),在某些层面上和寻找自己程序中的代码的方式是极为相似的。我在进行debug时,会首先进行非法输入测试和简单的边界数据构造,最后用生成的大型数据对程序进行“地毯式密集轰炸”,不de出bug死不休。一段优秀的样例,既可以用于自己的debug,也可以对别人的代码进行相同的测试,可谓是一举两得了。

  还有就是对别人的代码进行细致阅读了,比如第一次作业中,如果别人使用了正则表达式进行输入匹配,这时候就可以用大数据尝试爆栈(坏笑,jpg),换作状态机的话,则可以尝试各种***钻的匹配形式,总有一款bug适合你(再次坏笑)。还有就是可以发现一些细节的错误了,像是一个定义了长度为100的数组,而恰好101次输入不会报错,明显的会爆栈,这就又是一个4分(划掉),啊不对,一个crash。

五、心得体会

  1. Try-catch是个好东西。
  2. 面向对象思路有待进一步加深理解和使用。
  3. 永远不要小瞧OO的每一次作业,也大可不必产生畏惧,即,在战略上要藐视它,在战术上要重视它。
  4. 面向对象编码,始于详细的构思和顶层设计,行于简明的逻辑结构实现,完善于样例的“狂轰滥炸”。
  5. 无数次赶ddl的惨痛经历告诉我,早点开始一定没有错。

六、结语

  说了这么一大堆,其实只是一个前脚刚刚踏入面向对象大门的菜鸟的初试水。不过也真是因为如此才更显得其价值所在。希望之后的我,再次点开这篇博文,能够发出由衷的感叹“那时候可真是Too young啊~”。

  最后送给自己和大家一句虽被用烂但永不过气的一句话:

  

posted @ 2018-04-04 13:15  idealee  阅读(127)  评论(0编辑  收藏  举报