面向对象第一次总结作业
第一次作业
第一作业的主要难度在于判断字符串的格式。在写C语言代码时发现,如果输出格式错在哪里内容非常多,导致C语言虽然没有仔细debug,但依然写了好久。java使用正则表达式后可以简化很多,但输出错在哪里要增加的内容更多,所以只是对错误简单地进行分类输出。
正则表达式相关的类由Matcher和Pattern两个,所用方法:
1. match:如果匹配出的串太长会栈溢出,最终没有使用
2. find:每次只找出一个合法多项式就不会太长了,还可以用来将数字提取出来
3. group:用捕获组(就是按模式串中的左括号位置取出串)取数字更方便些
正则还有不少可用的东西,在以后的学习过程中还要继续熟悉。
关于类的设计,第一次的实践表现一般,由于任务简单,并没有变红的metric,圈复杂度压线合格。但还是由一些不合理的地方。其实可以把输入和计算功能分别独立成一个类而非都作为主类的方法以实现功能分离。
(下载插件费了好大力气,看了好几个教程,最后还是靠室友帮忙,简直怀疑是不是受了软件安装失败的诅咒)
debug:一个相当普遍的问题是输入为空时的问题。虽然最开始是因为系统有些问题导致输入为空时似乎输入了null而非空串(原理我不懂只是道听途说,不过不少人为此加了hasNextLine的判断),但系统改好之后空串依然是问题,我就发现了这样一个crash。
第二次作业
第二次作业要求实现规定的5个类,也就是帮忙完成了设计类的任务。这次的主要问题在于判断同质。我最终用六个类完成了任务(多了Main类,把main放到调度器里一堆static,很难受)。
最开始打算每次执行到下一个任务发生的时间,任务分为在队列中,已经发出等待执行和正在执行三种状态,可以直接看任务发出时刻的情况。结果实现的时候没写好状态转移过程(请求传丢了),修修补补过程中代码变得有些乱。
后来发现记录每类任务的上次完成时间就可以方便地判断是否是同质请求,就重新写了一遍。好实现的东西好debug,我没被找到bug,我匹配到的代码也是这么写,然后我也没找到bug。然而这样写没有可扩展性,导致我第三次作业继承的时候只继承了输入相关内容和属性,控制部分的代码一点都没用上。
第二次作业的圈复杂度就开始出问题了。我的类分为Building(楼层类,把各楼层及其中人当作一个整体,所以它负责输入),Request(请求类,将请求的三个东西放一起,简陋但还挺有用的),ReqQue(请求队列,先入先出,用的是库,后来感觉不如arraylist*,当初因为第一次作业最开始说不让用没敢用),Controller(调度器,写完了才发现名字叫schedule),Lift(电梯,实现的功能是完成当前任务)。
Building的输入由于分ER,FR两种分支较多,圈复杂度偏高(17),不过将提取出三个数(终点,时间,请求类型)后的判断分出来后就问题不大了。其他方法最大的圈复杂度也只有7了。
第三次作业
第三次作业的主要问题在于捎带。之前的方法虽然简单,但在这次转移失败了。发现又要回归到类似第二次作业最开始的实现了。电梯正在执行的任务由一个变成多个,等待执行的部分不再是队列而是会从中间抽取的。电梯每次执行一个操作(0.5秒走一层或1.0秒一次开关门),如果没有任务就跳到下一个任务的时间(不然执行不到发出时间极限晚的任务)。这次先想明白了任务转移的过程再开始写的,没再出问题。
这次的圈复杂度情况就比较糟糕了,有两个特大型的方法,逻辑复杂达到合理值的二倍多。但我发现我还可以抢救一下:这两个方法是由几个可以立刻分开的东西组成的,它们的功能不够内聚。ALS_Ctrl的run方法可以将输入过程和从待执行任务转到执行中的过程分出来。(这里突然发现现在的任务队列ReqQue其实没什么用,与待执行集合wait相关的任务都交给ReqQue执行好像更合理,队列干脆换成数组或arraylist,但这样调用的深度又增加了,在Main -> ALS_Ctrl -> Lift -> Request中间又插入了ReqQue,深度好像还行但逼近不合理了)。getIn和第二次作业一样将提取信息后的判断分出来就好多了。goOneStep还好。至于canCarry我明明就只就是把指导书的要求翻译了一下,救不出来了。。。
输出的顺序是这次比较容易出的bug,因为会有之前不捎带的任务变成捎带。为了解决这个问题采用了室友的方案:每次在已经发出的指令中找到最远的ER类的任务,更新终点但不添加任务,之后将可捎带任务加入。这样就可以不用单独存主任务了,也省去了按输入顺序标号再排序的过程。
总结
1. 实现问题。直接将引用返回这件事情知道上课听到之前都完全没意识到这是个问题。应该改成return x.clone();这种写法才相对安全些。写代码的时候完全没有圈复杂度的概念,就只是凭感觉地划分代码,所以并没有较好地满足这个代码规范。以后实现时要注意。
2. debug。主要依靠测试数据找bug,和身边的同学合作构造测试集,到第三次的时候还有大佬搭的网站(orz)。代码也会看,但是结果上基本都是靠数据找到了bug(这个时候倒是能看出代码哪里有问题了。。。真是呆)。可能因为大家的代码基本都比我长(有时会出现我二倍长的代码),我看了类名,方法名,属性名,几行代码,然后就觉得挺好的应该没啥了。还是要有耐心一点一点读代码才能提高吧。
3. 可扩展性。第三次作业时充分地感受到了实现的方便和可扩展性的矛盾。之前的代码要么是模板,每次都直接抄上去调用,一点都不用变,要么是写完了就再也不需要的代码。为了好写好调少干活(就是懒,也没干得快多少。。),我会尽量挑代码少的方式,没考虑采用有了新的需求好改的方式,导致第三次的电梯调度要从头构思,只有输入和一小部分代码留下了,剩下的都在重写中消失了。这次的不单独存主任务,用ER指令更新的策略不知会不会对之后的多线程造成不好的影响。以后要格外注意可扩展性了。
上一篇: 物联网火热,或燃起芯片行业并购大火
下一篇: 按手印认罪