三次oo作业
一、三次面向对象
多项式计算:
第一次作业虽然只是练习简单的字符串的匹配,但我需要从头开始学习Java和面向对象的思想。第一次面向对象写代码就会发现,难免又回到面向过程的思想上。我是先写完Java再写的C程序,虽然之后的C程序没有用正则表达式,稍微有些冗长,却感觉写起来顺手多了。这样的不习惯反而让我发现自己已经慢慢接受面向对象了,虽然整体上还是有一些地方使用过程化思想写的。这一次作业也让我进一步了解了正则表达式便利,but本次作业唯一的一个bug也是因为正则表达式。
了解了正则表达式之后,有些偷懒地,就像直接一次性匹配所有的输入,于是就输入了一串长长的正则表达式。在自己测试的时候分别测了20个项和50个数对两个边界,却没有同时测20个项每个项都有50个数对的情况,所以并没有发现自己的程序会因为迭代过深而没能挺过压力测试。这时候想插一句,try catch真是个好东西,虽然无脑try catch稍显暴力,却很有用。
第一次作业虽然花费了挺多时间,但代码比较简洁,复杂度也还可以。除了压力测试,并没有报出其他的bug。类图如下:
从类图可以看出,当时我对面向对象的理解并不是那么深刻,我一直觉得一个类就能搞定这些事了,最后是为了创造对象而写了一个Poly对象。从类图上可以看出,Poly对象只是简单地实现了多项式的加减以及最后输出多项式,将与多项式有关的操作都写到了这个类里面。通过这次作业,我感觉面向对象和面向过程比较显著地差异就在于:面向对象你是对对象进行这个对象范围所允许的操作,而面向过程是有一个公有的操作在那里,你去调用就好了。按照这种逻辑,程序一旦变得复杂起来,面向对象会让整个程序更加清晰,功能更加明确。
傻瓜电梯:
第二次作业开始写电梯,实现起来并不是太困难,却为第三次作业埋下了一个伏笔,能不能继承成为了一个十分关键的因素。先从类图看看我这次作业的实现:
基于Eclipse在写程序的时候对类的调用是非常方便的,我用了一个类表示报错,这是我通过阅读上一次被分到的那个同学的代码学习到的(原来我每次报错都在程序中写出)。ErrorReport类可以帮助我在第三次改了报错情况的时候很快地修改,并且不至于遗忘躲在某个角落的报错,导致最后会因为输出格式的原因无味的挂掉一些测试点。
Elevator类和Floor类分别管理了电梯内部按键的情况和楼层按键的情况以及同效请求的分析。对于判断同效请求我是通过三个数组(分别对应电梯内所有的楼层按键Elevator.button[11],所有楼层的上行键Floor.upbutton[11]、所有楼层的下行键Floor.downbutton[11])来对每个按键的作用时间进行记录,如果之后的请求是在该按键作用时间内即被判定为无效请求。然后每个请求进行判断后直接就加入到了Queue类中,而调度类非常鸡肋,也导致了我第三次作业的工作量增大。而Requesting类里面就是每个请求的一些特性,主要是记录的作用。
最后公测挂了两个点,竟然是因为在进行字符串判断的时候我用了”==”而不是”.equals()”。当然我也不是故意这么用的,而是在我其他的字符串判断都没问题的情况下,可能写那一段是在我某个神志不清的时候,在写十楼不能上一楼不能下的时候顺手就用了”==”,而最后我测试的时候想当然觉得这里应该不会出问题,就没有测。归根结底,还是——懒了一下。测我的那个人也非常仔细,找到了我在顺序上犯的一点小错误。
程序的复杂度如下:
嵌套深度和复杂度都体现在Queue类里面的addf()和adde()两个函数上,它们的作用分别是在队列里面加入电梯类指令和楼层类指令。因为我把很多该指令是否有效的判断里面了,导致这个Queue类本身就十分复杂。在完成电梯后,其实我马上就意识到了,有些判断完全可以移到前面去,可是功能都实现,就不想在改整个代码的结构了。然后,然后就害惨了第三次作业。
ALS电梯:
先看一看类图简单地意会一下吧。什么?看不清?的确看不太清,不知道能不能点开看高清大图。我可以说,主要功能段我几乎从我的第二次作业继承不下来,所以重写了所有的Schedule类,而且这一个类十分冗长,debug能de到眼瞎的那种。增加了EWork这个接口,通过这个结合实现了两个关于电梯和楼层判断的类,简单地说就是将之前那段冗长的判断拿了出来单独判断。并且是在输入RUN之后统一进行判断,而第二次基本上就是RUN之前就判断好了,等着输入了RUN就输出。第三次作业与第二次作业的主要区别就是这些。
接下来看一看复杂度:
迭代深度和复杂性还是一如既往地高,反映出了我一个非常明显的毛病,喜欢把很多判断挤在一起实现,其实完全可以放在其他类里面。不仅增加了复杂度,还给我debug时带来了很多麻烦。
二、BUG
1、我的bug
bug主要出在这几个方面:压力测试、”.equals()”的使用、以及对电梯调度策略的正确理解。
2、测别人的bug
三次被分到的都是大佬的作业,公测几乎都是全过的,readme读起来会让人有一种舒服的感觉。说是测bug不是说是向他么学习,读他们的程序学到很多不一样的实现,读他们的readme也会感受到他们的考虑是多么详尽。唯一一个稍有瑕疵的是第一次的作业那个同学的那个同学正则表达式有bug,也被公测捕捉到了,所以我剩下的只是学习。
3、怎么测bug
我一般会拿自己测过的数据先过一遍,然后读一读他的readme了解他和我不一样的要求,然后再读他的代码,看他在实现的过程中有没有什么细节没有考虑到,再针对找到的瑕疵构造数据。
三、心得体会
·程序的可继承性,作为面向对象的一个优势,不能光想着功能的实现,万一哪天你又需要这个功能你还能把它移植走,我觉得这样的类才比较有价值。
·开始写程序之前对自己的程序的结构有一个良好的设计与认识非常重要,能减少写代码时浪费的时间,也有减少bug加成。
·在慢慢熟悉Java语言后,我觉得应该有意识地去了解一下比如接口、子类父类、继承这些东西在这门语言里的意义,而不是指导书说了要用接口,就为了使用接口而去用,而是去了解一下它可能在工程量更大的项目中更有利于编程人员去重构与维护。