zoukankan      html  css  js  c++  java
  • 面向对象设计与构造2019 第二单元总结博客作业

    面向对象设计与构造2019 第二单元总结博客作业

    作业回顾

    • 2.1 单部傻瓜式调度电梯设计
    • 2.2 单部捎带式电梯设计
    • 2.3 多部智能型电梯设计

    一、三次作业的设计策略

    • 第一次作业只有正确性要求,没有性能要求,对于多线程的知识也没有过多涉及。所以我就无脑写了一个FAFS型,不含捎带的电梯。在正确性上有十分充足的保证,但是性能上很差劲,也没有什么可以说的策略。

    • 第二次作业加上了20分的性能分,但我并没有在性能上做出过多优化。我采用的策略是类似于磁盘扫描算法的LOOK算法,即模仿现实生活中电梯的算法。事实证明,这种调度策略在所有人的程序中并不算优秀。虽说我和其他部分人都是LOOK算法,但我在细节方面的实现非常粗糙,依然保留着上次作业的风格,并没有想尽可能多的去载人,而是尽可能让电梯路线不受牵制。这样,正确性虽好,但是性能分很低。

    • 第三次作业适当的扣除了性能分占比,让我们能更专注于正确性。我在写的时候,策略和第二次基本相同,所以正确性上没有很大问题。关于中转的问题上,我依然是选择牺牲性能来完善正确性。我将所有一部电梯无法送达的指令送到1层或15层(哪个近去哪),拆分成两条来处理。这样子正确性上有保证,但是效率依然不够。最后,我的性能分也并不理想。

    二、基于度量的分析

    1.时序图和类图

    • 时序图对于三次作业而言大同小异,多张图没有很大的参考价值,且占用空间。我在此放出第三次作业的时序图。可以看出,我采用的是生产者-消费者的模式,使用经典的生产者-消费者-容器三大类,对电梯运行进行有序处理。分发器采用notify的形式唤醒wait中的电梯,减少了CPU忙等待的时间。

    • 三次作业的类图也是大同小异,我在此一并放出。



    • 类图方面,可以看到类并不多,也没有建立过多类的必要。三次作业都以非常基本的设计模式构建。
    • 但是,就SOLID设计原则而言,我的程序做的并不够好。我的程序没有很高的复用性和广泛性,许多类的方法功能都写得比较死,是在面向对象的每个方法内尽情使用面向过程的思路进行编写。尤其是电梯的上下人开关门处理,一套过程性思路行云流水,却没有体现出对象之间的交互性。

    2.经典度量数据

    Type Name NOF NOPF NOM NOPM LOC WMC LCOM FANIN FANOUT
    Elevator 7 0 6 2 63 9 0 1 1
    Input 3 0 2 2 30 4 0 1 1
    Main 0 0 1 1 11 1 -1 0 3
    Switch 1 0 3 3 12 3 0 3 0
    Type Name NOF NOPF NOM NOPM LOC WMC LCOM FANIN FANOUT
    Elevator 11 0 16 2 223 57 0 2 2
    Main 1 0 2 1 44 6 0 1 3
    RequestList 3 0 5 5 25 6 0 2 0
    Type Name NOF NOPF NOM NOPM LOC WMC LCOM FANIN FANOUT
    Container 4 0 8 8 38 11 0.375 3 1
    Dispatcher 4 0 7 2 91 17 0 2 3
    Elevator 12 0 23 2 306 76 0 2 3
    Request 3 0 5 5 24 5 0 3 0
    TestMain 0 0 1 1 17 1 -1 0 3
    • 以上依次是我第一、第二、第三次作业的度量情况。可以看到,在代码行数(LOC)方面,电梯类Elevator一直是大头。三次作业中的电梯类代码行数占了总行数的50%以上,可以说将一切处理全部聚合在一个类中。这种设计并不算好的架构,但我本次作业又不知道如何去更好的拆分。
    • 第一次作业中,由于对生产者-消费者模型不熟悉,我甚至写了一个Switch类作为原子布尔型变量,作用是能够使得电梯线程停止工作。后面这种东西没有再出现。
    • 第三次作业中,程序的扇入扇出值较为合理,高扇入(FANIN),合理扇出(FANOUT),可以感觉到自己初步掌握了OO的设计诀窍。

    三、分析自己程序的bug

    • 三次作业中,我为了追求正确性从而牺牲了许多性能,后果是三次作业中我都没有被检测出bug。课下我使用自己的测评机进行大量数据反复测试,得到的结果也十分稳定。所以在这里,我没有很多可以分享的内容。
    • 助教曾经提到过,输出类TimeableOutput不是线程安全的。但是我在实际编写程序的时候,无论锁不锁输出,对结果都没有影响。虽然我锁了,但是我依然没有弄清楚不锁可能带来的问题。

    四、找别人bug的策略

    • 我坚信,越往后写,代码量越大,通过阅读他人代码的方式来找bug的行为会越发艰难。而且哪怕他人的代码有错,自己的思维也会非常容易被带入他人的错误写法中,从而导致一时间找不出错误。所以,我选择使用自动评测的方式,来寻找他人的bug。
    • 一台自动评测机器所需要的基本功能:
      • 随机数据生成功能
      • 编译运行、控制输入输出流的功能
      • 输出结果正确性判断功能
      • 判断结果可视化导出功能
    • 就这次的三次作业我自己写评测机的经验而言,难点在第二点,工程量大的重点在第三点。第二点是许多同学写出像样评测机的门槛,也就是定时输入的功能,给许多同学带来了困扰。这里我采用Python自带的subprocess模块来解决问题。此模块可以控制定时投放数据,也可以关闭输入流,非常方便。
    • 而输出结果的正确性判断,只是简单的逻辑问题。指导书中对于正确性判断说的十分清楚,我们只需要把助教的言语转化为代码就可以完成此功能,但是这个工程量未必比写一台电梯要小。所以大家可以量力而行。到第三次作业的时候我已经完全摸了,拿了第二次的程序改成三台电梯直接用了,没有实现特定楼层、超载判定等功能,有点可惜。

    五、三次作业的心得体会

    三次作业下来,我切实的体会到了OO思想和OO课程的特点。面向对象程序设计特有的设计模式,和多线程特有的设计模式,都超脱于之前学的所有知识,让我于困境之中发现了更多的惊喜。虽然电梯功能很简单,但是从其中学到的东西和面向对象的知识,远远超过之前的求导程序

    多线程的学习中,线程安全很重要。线程安全的设计要点,在此之前的程序设计中从来没有涉及。对于临界资源的操作要谨慎再谨慎,是多线程有风险而有魅力的点。另外,wait()和notify()的使用要比忙等待更加节省资源,也是多线程设计中非常智能的设计功能。

  • 相关阅读:
    win2003系统网络安装——基于linux+pxe+dhcp+tftp+samba+ris
    Linux系统网络安装——基于pxe+dhcp+nfs+tftp+kickstart
    写在前面
    windows下使用批处理设置环境变量
    使用广告终结者屏蔽页面的任意部分
    window7 输入什么命令可以快速打开服务管理?? 虚拟机设置了NAT网络连接方式,还是无法上网?
    [转]PHP100视频教程(2012-2013版)下载地址及密码
    窗口对象的方法 prompt() 用来输入数据
    HTML5 canvas标签绘制正三角形 鼠标按下点为中间点,鼠标抬起点为其中一个顶点
    javascript弹出框打印某个数值时,弹出NaN?(not a number)
  • 原文地址:https://www.cnblogs.com/sharinka0715/p/10753914.html
Copyright © 2011-2022 走看看