OO第一次总结

时间:2021-02-20 17:25:35

 

一.代码度量分析&bug情况

1.多项式加减

  写第一次作业时候不要说OOP,连用JAVA打HelloWorld都不会,所以写了一个完全面向过程的程序,就两个类,其中一个类还是为了满足指导书要求随便写的.所以实在没有什么发类图的必要.

  写的时候自己发现了一个bug,正则表达式太复杂而且一次匹配整个输入,导致如果输入太长会爆栈,查了一下matcher类的文档,改成用lookingAt()方法来一次截取一个多项式,这样修改之后就不会爆栈了.

  然后改完了这个bug没有再测试一下输入空格的情况,以为之前测过了不会有问题,结果输出空格会抛出一个异常,互测被人报了一个bug...得到了修改后要重新覆盖测试的体会...

  由于大部分逻辑都写在了main当中,而且程序写得也不好,理所当然的圈复杂度和内嵌块深度标红了.

OO第一次总结

 

2.简单电梯

  除了实现基本类以外,自己多加了一个inputHandler类,当时还觉得叫这个名字会不会太土,结果总结课上ppt给出的类也叫这个,把输入处理单独划分一个类算是一个小小的进步吧...floor类因为自己的设计用不上,也不想很牵强去用又不能不写,就写了一个但没有实例化过,在类图里就删去了.

  然后自己对请求划分了两个层次,一个父类,FR和ER从父类继承,现在看来其实没有什么必要,不过从这里学习到了一点继承的知识.downcast,upcast,override,引用类型和构造器的关系之类的.  

  这次的作业因为逻辑比较简单,没有被报bug,写完自己测的时候也没有什么大问题,感觉比第一次作业简单,可能是有进步了吧(错觉).

  通过这一次作业初步体会到了面向对象的设计方法,这次main函数就很简洁,只有几行声明引用和调用构造方法,感觉像造好了几个积木,然后拼起来就可以了.

  由于输入处理逻辑写得不是很好,把请求初始化的逻辑也放在inputHandle方法里,所以圈复杂度红了.

OO第一次总结

OO第一次总结

 

3.ALS电梯

  这次的作业写得很失败,最主要的原因是调度的算法在逻辑上就是错的.具体的逻辑错误没有太大意义,不加赘述了.

  问题在于我在周三发现了这个bug,还有两个多小时改却没有改过来,最后还是带着bug交了,最后公测挂了两个,测试我的人很温柔,只扣了我一个点(感谢他).这一方面说明我测试的能力真的很弱,没有花心思去构造好的样例.另一方面暴露了代码的结构也很乱(看得少写得少),虽然我把同质的判断,捎带的判断,对队列的扫描都拆分成了不同的方法,然后通过scheduler来调用它们,但是没有区分好方法各自要做的事情,同质请求的输出和同层捎带的输出逻辑混杂在一起,虽然在大部分情况下都能正确输出,但是在某个情况下,调度算法是错的导致输出是错误的,而由于这两部分耦合太严重,改了一个就要动另外一个,最后改得我自己都认不出来,只好测一下其他情况是不是还是对的,然后带着bug提交了.这种情况下git reset一下然后拉出一个新分支重构应该是更好的选择.

  这次作业的类继承第二次作业,所以类图是相似的.但是从metric上可以看出和简单电梯不同的是,圈复杂度标红的原因变为了schedule方法,而嵌套深度也被标红了.这次我把命令初始化的逻辑交给命令类来完成,简化了inputHandler的逻辑.但是由于要支持捎带并且一开始没有做好设计,在schedule了里加入了大量判断分支语句,导致了圈复杂度过高.嵌套深度标红的原因是run方法,这是一个调动电梯运行的方法,是一个大包大揽的方法,应该说是god method,其内部调用了同质判断,捎带判断,电梯动作等多个方法,依赖它们的返回值和电梯状态做了大量逻辑判断,导致耦合度很高,难以修改.

OO第一次总结

 

二.测试别人程序的情况&测试策略

  测试别人的程序和测试自己的程序策略差不多:

  1)根据各个功能构造一些基础测试点,测试基本功能

  2)构造一些边界情况,压力测试

  3)读代码,找逻辑错误

  因为我抽到的三次作业都是公测全对的,所以其实第一步操作基本没有意义,比如输入的一些检测,与其傻傻的对着readme构造完备的输入测试集,或是生成随机输入,还不如直接看看他的正则表达式和输入处理逻辑有没有什么漏洞.而且读别人的代码也能有一些收获,所以三次我都完整读了一下(主要代码量也不大),最后一个bug也没找到...光被别人扣分了...

  第一次抽到的作业对方写的比较面向对象,给只会面向过程的我带来了一点启发.比如他将报错信息单独抽象出了一个类,每次都调用类方法就好了(虽然报错的逻辑有问题),现在看来有点像异常抛出机制.而我是直接print出来...

  第二次抽到的作业对方写的跟我的很类似,我感觉大家半斤八两,也没什么收获,现在对他写的是什么都没印象了.
  第三次抽到的作业采用的抽象感觉蛮有意思的,把电梯和楼层的按钮也当成对象,然后有点亮熄灭两种方法,判断同质或者捎带的时候就查询按钮的状态(本质上就是加了个状态位).他的scheduler类虽然我找不到bug,但是一个方法有290行...判断同质请求,捎带请求,运行电梯的逻辑全部连函数抽象都没有地掺杂在一起,看挺久才看懂,然后佩服他能不乱.但是我觉得这样的写法真的不值得学习,要避免写出这样的代码.

 

三.心得体会

1.测试先行

  阅读指导书后先不忙着设计程序,而是先构造测试样例.在阅读指导书的过程中难免有些遗漏和理解不透彻的地方,通过构造测试样例可以加深对指导书的理解,发现自己没发现的细节和坑点,避免写完程序发现漏洞后再来修改,也可以在设计程序的时候提供一些指导性的信息,避免盲目写代码.

2.做好设计再码代码
  我AMD单核的小脑袋总是弄混两个类之间的分工,一个类写着写着就忘了它要实现什么功能,所以会写一个文档或者在纸上画一画(写readme还能用一用).这样做也能在实现的时候大概估计一下自己的进度,不会产生离完成还遥遥无期的感觉.但是也要避免纠结于细枝末节,比如用String还是StringBuffer等到实现时再考虑.
3.修改和重构
  代码的改动有可能会带来新的bug,所以在逻辑有修改后要重新覆盖测试一遍.如果类方法之间的耦合性很高,修改一个地方造成"牵一发而动全身",个人感觉还是直接重构出问题的部分.关键还是要设计出低耦合的代码.

4.困惑

  虽然说要"高内聚,低耦合",但实际上并不十分清楚怎么设计出这样的代码,只是在编码时有一个朦胧的意识将两个部分拆分开来,还是要多写多看多思考,但是又没有能力判断什么是好的设计,如果能提供一些好的样例供阅读学习就好了.