面向对象第二单元作业总结

OO第二单元作业总结

第一次作业

作业任务描述

设计一个单部多线程傻瓜调度(FAFS)电梯的模拟, 输入为人的ID, 起始楼层和终点楼层, 电梯调度算法要把人送到指定楼层。

问题建模

在这次作业中, 我对问题用一下的方式建模

人在终端中输入请求, 进入request pool, 然后一个电梯从request pool中拿请求。

请求-》进入请求池-》每当电梯没有任务时, 尝试从请求池中拿一个请求

其中, 电梯为单独的一个线程, 请求池为一个单独的线程, 主线程为一个线程。

实现与类图


这次主要功能在三个类中

  • RequestPool
    这个类用于获取请求, 每次得到一个请求就把这个请求放到ArrayList里
  • SingleElevator
    电梯类, 用于管理乘客上下以及获得请求。
    每个电梯单独开一个线程, 线程的主要函数如下

    一共有以下三种情况
  1. 内部有请求
  2. 外部有请求
  3. 没有请求

这次作业基本还是使用轮训+sleep的机制, 不断检查是否有请求。
每当得到请求时会先到请求的层

然后接上乘客, 把乘客送到目标楼层

线程分析

这次线程比较简单, 没有使用wait和notify的方法, 之后会有用到。

度量分析


第一次作业整体比较简单, 复杂度控制的还比较好, control flow和design complexity都没有太复杂的情况, 类内部的聚合程度, 和类之间的耦合程度做的也还不错。

第二次作业

作业任务描述

在第一次作业的基础上, 加入捎带调度策略。

问题建模

沿用第一次架构, 但是每次电梯在到达一个楼层后会判断是否有和当前运行方向相同的乘客, 如果有的话, 那么电梯会捎带上这个乘客。

实现与类图


这次和上次作业基本没有变化, 还是主要三个类, 其中修改了电梯类。
在每个楼层检查有没有人进入, 有没有人出去

checkInAndOut()会调用checkIn和checkOut

这两个方法会检查有没有人在当前楼层是目标到达楼层, 以及reqPool里面是否有请求从这一层上, 并且判断到达楼层是否在运行的方向上。

线程分析

这次线程用了wait和notify方法, 每次没有请求时会wait request pool, 每次request pool得到一个请求时会notifyall 来解决忙等问题

度量分析

这次作业和上次作业基本没有添加任何代码, 因此复杂度和前一次作业基本类似。

第三次作业

作业任务描述

这次作业的内容如下

需要同时使用三部电梯, 并且每部电梯的使用楼层有限。

问题建模

这次问题依然沿用上次的架构, 稍微修改下乘客上下的条件即可。
A,B,C电梯分别负责不同的楼层, 设定1层为换乘点, 在get request修改每个电梯可以获得请求的楼层就可以完成这次的任务。

实现与类图



在获得请求的时候, 加入了一些条件。
A电梯负责-1, -2, -3层, 和16-20层, 剩下的B和C电梯分别负责奇数和偶数层, 并且优先获得直达的顾客。
在乘客出电梯的时候, 需要判断这一层电梯是否可以停靠

此外, 在这次作业设计的时候, 还需要考虑电梯容量

我通过检查当前电梯的大小和最大大小是否相等来判断还可不可以再上一个人。

线程分析

和前两次作业相同, request pool为互斥访问, 三个电梯为三个独立的线程, 当没有任务的时候,同时等待request pool获得任务, wait(), 每当request pool获得任务后, 使用notify来唤醒三个电梯。

度量分析


在这次作业中,control flow复杂度做的不是很好, 之后还可以改进if语句, 不要有过多的分支。

Bug发现和解决

自己的代码在强测和互测中都没有被发现bug。

心得感受

从这次作业中, 我感受到了架构的重要性, 一个好的架构是可以沿用到很多次作业里的, 像这个单元的作业中, 我在第一次作业上花了一些时间思考架构, 第二次作业对代码基本没有修改, 第三次作业改了一些条件判断的语句。
我体会到, 好的设计可以减轻后面的工作量, 十分重要。

posted @ 2019-04-20 21:31  edward-crazy  阅读(213)  评论(0编辑  收藏  举报