blog-电梯调度问题及迭代总结

OO前言
根据三次题目集5~7,以单部电梯调度程序为核心,通过不断迭代新功能的过程中,我也对面向对象程序设计有了深入的了解(只是过程太难了,极易红温):

  1. 本次迭代性编程中,我懂得了许多知识点,例如:正则表达式,List与泛型,类设计等一系列知识。
  2. 题量总的来说其实并不多,编程时间是充裕的,有较多的思考时间。
  3. 题目难度适中,万事开头难,题目5我并没有找到合适的方法去解决(就是没写出来),但其实慢慢地深入后,题目6~7编程思路也愈发清晰,愈发得心应手(写出来了)。
  4. 对IDEA(简单的构造方法着实好用)等编程工具的使用也慢慢熟练起来。

OO设计与分析
第一次作业
1.1 题目
单部电梯调度程序
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求)。

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。

电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
输出格式:
模拟电梯的运行过程,输出方式如下:

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
1.2 设计类图

1.3 Source Monitor报表

1.4 分析

  1. Lines(172行):代码行数为 172 行,不算特别庞大,但也并非极简。
  2. Statements(107 条语句):语句数反映代码实际执行操作数量。107 条语句与 172 行代码对比,若代码行与语句数比例接近 1:1,代码可能较紧凑;而此例中比例约为 1.6:1,说明有空行、注释行等情况,需要引起重视。
  3. Percent Branch Statements(26.2%):分支语句(如if - else、switch等)占比 26.2%,代码逻辑较为复杂,增加了理解和维护难度。
  4. Method Call Statements(72 条):方法调用语句达 72 条,占总语句数比例较高。
  5. Percent Lines with Comments(8.1%):含注释的代码行仅占 8.1% ,注释比例较低,不利于代码的长期维护。
  6. Maximum Complexity:最大复杂度为 6,最复杂的方法已经有一定的逻辑复杂度,存在过多的嵌套条件或循环语句,需要降低复杂度。
  7. Average Complexity:平均复杂度为 6.0,说明大部分方法都有一定的逻辑复杂性,整体代码的维护难度相对较高需要对代码进行优化。。
  8. Maximum Block Depth:最大代码块深度为 5,过深的嵌套会使代码变得复杂,增加了代码出错的概率。
  9. Average Block Depth:平均代码块深度为 2.35,说明整体代码的嵌套情况处于中等水平 。
  10. Line Number of Most Complex Method:最复杂方法所在行号为 141 行,该方法是Main.main(),它的复杂度较高,存在较多的逻辑判断和嵌套结构 。

第二次作业
2.1 题目
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP)。
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>

2.2 设计类图

2.3 Source Monitor报表

2.4 分析

  1. Lines(295 行):代码行数为 295 行,相较于第一次作业,代码规模有所增大,但只是功能没什么变化,解决了电梯类职责过多的问题。
  2. Statements(162 条语句):语句数代表实际执行操作数量。295 行代码对应 162 条语句,比例约为 1.8:1。
  3. Percent Branch Statements(19.1%):分支语句(如if - else、switch等)占比 19.1%。
  4. Method Call Statements(119 条):方法调用语句达 119 条,在总语句数中占比较高。
  5. Percent Lines with Comments(2.4%):含注释的代码行仅占 2.4% ,注释比例低,后期回顾代码时可能会面临较大理解困难。
  6. Maximum Complexity(最大复杂度为 9):最大复杂度达到 9,说明最复杂的方法逻辑相当复杂,是因为存在大量嵌套条件或循环,必须考虑重构以降低复杂度,提升代码可读性与可维护性。
  7. Average Complexity(平均复杂度为 3.00):平均复杂度为 3.00,说明整体方法复杂程度不算太高。
  8. Maximum Block Depth(最大代码块深度为 6):最大代码块深度为 6,与第一次作业出现问题相仿。
  9. Average Block Depth(平均代码块深度为 1.54):平均代码块深度为 1.54 ,整体嵌套情况相对不算严重。
  10. Line Number of Most Complex Method:最复杂方法为Main.main()且在 257 行,此方法逻辑复杂,有较多逻辑判断和嵌套,需要着重关注。
    第三次作业
    3.1 题目
    对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP)

    电梯运行规则与前阶段相同,但有如下变动情况:
    乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
    对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)。
    3.2 设计类图

3.3 Source Monitor报表分析

3.4 分析

  1. Lines(314 行):代码行数为 314 行 ,代码规模进一步增大,新增功能,使实现更为丰富和复杂。
  2. Statements(170 条语句):实际执行操作的语句数为 170 条 ,代码行与语句数比例约为 1.85:1。
  3. Percent Branch Statements(18.2%):分支语句占比 18.2% ,整体逻辑复杂程度尚可。
  4. Method Call Statements(121 条):方法调用语句达 121 条 ,在总语句数中占比较高。
  5. Percent Lines with Comments(2.2%):含注释的代码行仅占 2.2% ,注释比例依旧是极低与前两次作业基本相同。
  6. Maximum Complexity(最大复杂度为 8):最大复杂度为 8 ,最复杂的方法Main.main()逻辑复杂程度较高,存在较多嵌套或条件判断。
  7. Average Complexity(平均复杂度为 1.88):平均复杂度为 1.88 ,整体方法复杂程度相对不算高,但鉴于最大复杂度较高,仍有空间。
  8. Maximum Block Depth(最大代码块深度为 6):最大代码块深度达 6 ,有前两次作业的较深的嵌套。
  9. Average Block Depth(平均代码块深度为 1.55):平均代码块深度为 1.55 ,整体嵌套情况不算严重。
  10. Line Number of Most Complex Method(最复杂方法所在行号为 275 行,方法是Main.main()):最复杂方法Main.main()位于 275 行。

OO踩坑&&心得

  1. 由于这是第一次大作业,尽管已经有思想准备,但从之前最多一百多行代码再到大作业的三百多行,我当时是一头雾水,String类和泛型等等当时也是懵的,类设计更是一窍不通,什么也不懂,这就造就第一作业的false,所以要学好理论基础(记得),没有它,就像西方没有了耶路撒冷。
  2. 不要急于写代码,之前的类设计和方法的构造以及设想的功能实现更为重要。一开始没有仔细审题,例如对电梯运行的方式并没有认真考量就开写,导致一个测试点都没过,而后,题目要求也没仔细看导致出现例如up,down,end大小写的问题,这些都应该避免。
  3. 查错的效率太慢了,很容易造成一个错误却耗费大量时间(总是运行超时),因此需要锻炼。

OO改进建议

  1. 应该及时将C语言的面向过程的思想转变为Java的·面向对象思想,防止代码出现耦合程度较高,复用性差,不能遵守单一原则等问题,需要尽快改正。
  2. 减少if-else等逻辑语句的使用,造成代码复杂程度过高(与第一点有关)。
  3. 增加代码注释的比例,尽量做到见注释就清晰代码的功能。
  4. Java的语法知识需要加深,防止进入有思路却苦于没有方法的窘境。
  5. 多点想象力和创造力,对类设计有更好的灵感。
  6. 练打字速度(真的慢)。

OO总结

  1. 在前言中我就写了我从中获得的一些知识点,的的确确感觉这门课不简单,但还是得努力学啊。
  2. 总之,三次的题目集训练让我收获颇丰,不局限于只会敲代码,思路和观念的改变更为重要,有运行不通过的沮丧,有意外通过时的审查,我发现了许多问题,也解决了很多问题,我是充实的。
  3. 同时希望题目的测试用例和测试点可以多一些,0分和满分的落差实在是有点大,测试用例少会导致实现样例有特殊性,过了却还是错误,无法得分,希望接下来有所改进。
posted @ 2025-04-20 19:24  霖伶  阅读(31)  评论(0)    收藏  举报