面向对象第二次总结性博客

第五次作业

一、度量分析

  通过Metrics图给出的度量分析可以看出,本次作业在Scheduler类的run方法圈复杂度和块嵌套都过高,主要原因该方法承载了大部分的程序工作,在处理这些工作时使用了过多的if_else嵌套。这在第一次总结性博客中也有提到,而我也在努力避免这个问题,但可能函数封装还做得不够好,从而导致了这一问题。

  在Scheduler的构造器中,由于我传入了3个电梯对象以及它们的请求队列、输入请求队列和系统时间,从而导致了过多传参的问题。这可以通过电梯类中写入电梯请求队列以及将系统时间作为static对象存在在eleSys主类中供其它对象调用来避免。

二、类图

  先对图中的类进行解释,Request类是请求类,用于请求对象的实现和信息获取;RequestQueue类是请求队列类,用于待处理请求队列和电梯附属请求队列的实现;Elevator类是电梯类,用于电梯对象的实现和电梯状态获取;Scheduler类继承了第三次作业的ALS_Scheduler类,并对请求调度方法进行了重写;InputHandler类用于处理用户的输入,并将正确输入生成请求对象存入待处理请求队列;eleSys类是主类,用于创建输入线程、三个电梯线程和调度线程,并启动这些线程,是他们实时处理用户输入。

  这样分类的优点是使功能实现得到保证,并且逻辑比较清晰。

三、sequence diagram

 

  in是输入线程,sche是调度器线程,ele1、ele2、ele3分别是三个电梯线程。如图所示,当待处理请求队列为空时,sche需要wait(),由in线程有新输入来唤醒;sche与三个电梯线程间也有交互,当某一个电梯线程拿走请求时,sche线程需要wait(),当有电梯改变其状态时又需要唤醒sche线程来进行调度。

  总的来说,整个程序的线程以调度器为核心,通过调度器的wait和notify来使整个程序维持它的正常功能。

四、BUG你我他

  本次作业我找到的bug主要是一些调度处理的问题。我拿到的代码在处理多条请求时,无法实现电梯间的正确调度,尤其是运动量的处理问题,程序无法把请求交给正确的电梯。除此之外,他/她的程序还有线程的问题,这也是本次作业的难点所在。

  在这次作业中我被找的bug主要是真时间造成的时间误差和线程的问题。

第六次作业

一、度量分析

  通过Metrics图给出的度量分析可以看出,本次作业在monitorTrigger类中,workPCG方法的圈复杂度过高,主要原因是使用过多的if_else嵌套;workRNM的块嵌套过高,也是由于过多if_else导致的。

  其他部分代码没有太大的问题,但仍需要进一步改善。

二、类图

  先来解释一下这些类,monitorTrigger类是监视线程类,实现文件或目录的指定监视功能;InputHandler是输入处理类,主要读取用户输入并将其存成monitorTrigger监视对象;SafeFile类是文件的安全类,用于实现文件的安全操作;TestThread类是测试线程,供测试者使用;SysMain是主类,其使用的Summary类和Detail类用于之后的结果文件输出。

  这样分类的缺点可能是监视线程类过于复杂,可以通过一个新类来存储监视器的属性,再给每个监视线程存一个监视器对象,这可以在一定程度上可以改善程序。

三、sequence diagram(以三个监视器为例)

  测试线程tt在用户的监视输入完成后启动,进行测试线程内的操作,当触发器扫描检测到文件或目录变化便会执行相应的触发器操作,完成后又会返回测试线程。

  整个程序以测试线程为主线,触发器线程扫描文件和目录来获取相应信息从来做出正确判断。

四、BUG你我他

  本次作业我找到的bug主要是线程安全方面的问题,这也是本次作业的重点和难点,当加入十几个监控线程,他的程序就会做出错误的相应。

  本次作业我被找到的bug主要是文件操作方面的问题,因为一个需要由被测试者提供的文件操作方法有误,导致测试者使用后出现了不正确的结果,这也警醒了我日后需要更加注意一些细节。

第七次作业

一、度量分析

  通过Metrics图给出的度量分析可以看出,本次作业Taxi类中的work方法圈复杂度较高,主要原因是使用了较多if_else嵌套;InputHandler类的块嵌套较高,主要原因是对于输入的判断使用了过多的判断条件。

二、类图

  先来解释一下这些类,Taxi类是出租车类,用于出租车对象的实现和出租车状态读取;TaxiQueue类是出租车队列,主要用于所有出租车的储存和调度;Request是请求类,用于乘客请求对象的实现;RequestQueue是请求队列类,用于乘客请求的存储和读取;InputHandler是输入处理类,将用户的输入存为乘客请求对象并加到请求队列中;Scheduler是调度类,用于读取请求队列和出租车队列,并进行正确的调度;Map是地图类,存储地图信息供其他对象读取;Main是主类,存有static地图对象供其他对象读取。

  这样分类的优点是条理清晰,且程序将出租车队列作为线程,这样的好处是每次改变所有出租车状态只要跑这一个线程,避免了100个线程同时运行可能存在的问题。

三、sequence diagram

  程序以调度器线程为核心,当请求队列为空时,调度器线程等待新输入请求,输入后重新唤醒调度器线程;当调度器发现有乘客请求可以被出租车接单时,等待出租车状态改变后再进行调度扫描。

  这样设计的优点是结构更加清晰,且使用一个出租车队列线程来管理出租车,避免了100个出租车100个线程可能导致的问题。

四、BUG你我他

  本次作业找到的bug主要是输出信息方面的错误,这也是在保证功能正确的同时需要注意的一点。

  本次作业被找到的bug是关于一个地图边界的问题,这是写代码时粗心导致的。

三次作业多线程设计策略

  在这三次作业的训练中,我逐渐地提升了对于程序多线程的理解,也在处理一个又一个bug中对设计策略有了自己的一些理解。

  第五次作业最先考虑的就是调度线程的设计,因为调度线程是这个程序最主要的线程。首先考虑到调度线程与输入线程间的关系,当调度线程发现请求队列为空时,需要wait,并等待新的输入来notify;其次考虑到调度线程与三个电梯线程的关系,因为三个电梯线程需要不断的更新状态,所以调度线程每次给最新状态的三部电梯分配完任务后就需要wait,等待某部电梯状态的改变后再唤醒调度线程。

  第六次作业最先考虑的是触发器线程的设计。触发器首先需要实现基本功能,并考虑实时监控的问题。因为触发器个数通过用户的输入来决定,所以我想的是一个触发器一个线程,只要保证它们之间互不干扰就能做到线程安全。测试线程只是模拟手动操作,只要使用SafeFile类的方法操作,不会存在什么问题。

  同第五次作业一样,第七次作业最先考虑的是调度线程的设计。首先考虑到调度线程与输入线程的关系,当调度线程发现请求队列为空时需要等待的输入线程新的输入。其次需要考虑调度线程与出租车队列线程的关系,每次调度器扫描后需要等待出租车状态刷新来唤醒。

感悟总结

1、在设计方面,我认为要像老师上课时说的那样,首先设计好整体的框架和类再来写代码,这样不但能事半功倍,而且能提高程序的正确性。

2、这阶段的训练让我们从面向对象的设计慢慢转到更为困难的多线程设计,但这对我们来说也是一次自我的提升。

3、慢慢学会了简单的多线程测试方法,并用在了对他人代码的测试中。

4、在测试他人代码的过程中,除了寻找他人代码的漏洞和不足,更多的是学习到他人程序设计的长处。

5、OO这门课更加地从设计层面上锻炼我们的能力,而不仅仅是代码实现能力。

6、希望自己能保持着认真的态度和不屈的意志战斗到最后。

猜你喜欢

转载自www.cnblogs.com/062297Coding33/p/8976386.html