OO第二阶段总结

(1)设计思想简介

OO第五次作业

  三电梯调度作业中,第一次尝试了java多线程编程,对多线程控制的理解及其浅显,仅仅采用了synchronized和sleep的方法来避免多线程的冲突。即电梯每100ms扫描一次状态,调度器每100ms分一次任务,并且用sleep把两者错开来防止冲突产生。但是由于运算本身消耗时间,在超大数据的测试下,两者会渐渐交合,还是会出现问题。

OO第六次作业

  IFTTT文件监视作业中,对多线程的认知有所加深,使用了锁代码块的方法来防止进程不安全的问题产生。同时也重写了file类,来确保进一步的线程安全。

OO第七次作业

  第一次打车作业中,进程不安全的情况较少,处理起来较为容易,通过整合调度器,即每个周期扫描一次调度队列,而非每个请求单独一个线程,有效地避免了冲突。

(2)基于度量分析代码

OO第五次作业

类设计如下:

事实上电梯逻辑本来很简单,即每一个请求进入队列后,由分配器分配给电梯,如果是电梯内请求,就直接点亮电梯内的按钮。如果是楼层请求,就按优先级将按钮点亮并记录由哪台电梯来相应,即FloorButton类中elvId这一属性。这也变相地为每台电梯就构造了一个请求队列。而电梯自己运转的方法和以往的作业一样。但是考虑到输出的问题,每个电梯还需要记录自己请求的详细信息,为了满足要求,这里直接将request的序号记录在了button类中,实属不智。

但是,在度量层次上却出现了极大的问题。

可以看到,在圈复杂度和嵌套块深度上电梯类均出现了过于复杂的情况。没错,在之前的作业中,调度器负责告诉电梯干什么,电梯只需要向哪走就行。而本次作业,调度器负责的是把任务分给电梯,但电梯自己还需要判断先执行哪个后执行哪个,相当于集成了之前作业的Scheduler,在实现上,由于scheduler的任务和电梯是完全同时的,所以设计成了一个类,一个线程,却在度量上出现了大问题。

 

OO第六次作业

类图设计

本次作业采用了每个触发器一个线程的思路,但是在实现上为了统一出现了一些不明智。

由于path-changed的存在,当其检视对象为文件时,需要检视文件的父目录,当我在线程中扫描本文件消失时,便会扫描文件父目录下的所有目录以检查文件移到的位置,但是我将renamed也设计成了一样的逻辑,只不过一个是限定,一定不在父目录下,且名字一样。一个限定一定在父目录下且名字不一样。但是扫描时使用了相同的遍历方法。这导致了一些bug的出现。

圈复杂度始终是无法逾越的难关,由于输入的不确定性,对输入的判断往往伴随着很多ifelse,本次作业光合法就有10种情况。。。这便导致了main中对输入的处理的复杂度过高。。。

 

OO第七次作业

 

圈复杂度几乎是没有问题,但是嵌套块深度过大,经过一番查询,发现在调度过程中首先扫描了队列中的请求,每个请求又扫描了所有的出租车是否符合条件,当抢单窗口关闭时,又要扫描所有的符合条件的出租车来确定派单给谁,三层大循环加上无数的逻辑判断导致代码块过深。

(3)bug分析

OO第五次作业

第五次作业出现了一个bug,出现了在某些及其稀少的状态下请求丢失的现象。

但调试信息却显示请求被正确地分配给了电梯,且电梯正确地接收到了指令,但却没有执行。

测试他人bug的时候发现了对方在实现中出现了当电梯都被占用时,新进入的指令不会被分配给符合条件的电梯的情况,大概是判断逻辑中对比部分出现了失误。

OO第六次作业

第六次作业出现了当父目录过深,扫描所需时间过长导致测试线程的下一步操作已经进行,导致recover失败的情况。应该使用更安全的线程控制,而非单纯地sleep,扫描结束之后才交锁可能比较好。

测试他人bug时发现了一些sizechanged时不触发modified的情况。

OO第七次作业

第七次作业并没有被测试出bug

第七次作业并没有测试出对方的bug

(4)总结

总的来说,对多线程的认知是越来越深,又学了os,对同步控制也不仅仅是synchronized这么简单,在写代码时也思考了很多关于面向对象思想和多线程控制方面的方法,确实是收益颇多。基于度量来看,总有一些代码的情况分类过多,导致逻辑复杂度较高。但是在当前情景下,我已经尽量地分配了职责,似乎有些类的职责确实复杂,有的类就是比较简单。。

 

posted @ 2018-05-02 15:39  SephyLi  阅读(220)  评论(0编辑  收藏  举报