一. 前言
5—7题目集针对电梯运行过程及算法实现进行了三次编程代码迭代,由最初的单一电梯类及其主类到第二次及第三次的电梯的多类设计。本次电梯算法迭代作业涉及了Java的基础语法知识、类与对象、异常处理、字符串、包装类(Integer类等)、枚举与泛型、正则表达式、集合框架等Java编程知识以及单一职责原则等Java设计准则。该次作业充分体现了Java面向对象的设计思想及对解决生活实际问题的重大作用。
就本次作业而言,题量适中,在充分锻炼学生的编程能力和算法构建能力的同时也合理控制了时间成本;在难度方面,本次迭代主要以培养和考察实际问题算法实现为核心,对初学者具有较高的编程难度。
二. 问题分析

1. 第一次迭代作业

**代码运行结果**

**问题层面分析**

在编写第一次电梯程序迭代作业时,最后的试题样例的运行结果与预期结果存在着细微的输出差距,同时结合老师之后给出的补充样例数据发现在相同的运行状态的输出也存在着相同的运行和输出错误。仔细分析第一次大作业过程,个人存在着多方面的问题。
首先是心理层面的问题。在进行第一次大作业的过程中,由于在已知其难度超出平均水平的情况下以及对自身的一些心理暗示,大多数状态下都表现出未战先怯的想法,致使在安排的时间计划中很多时候都不能集中精力和注意力在分析和思考上,形成了负向循环。同时在最后的时间中放弃了进一步修改和尝试。
第二是知识基础层面的问题。第一次大作业的过程和算法实现中主要考查的是对Java基础知识的综合及灵活运用以及涉及关于Java面向对象技术中的包装类、队列等部分知识的辅助运用,需要我们进一步熟悉融汇基础知识并做好对部分知识的自学和了解。在编写第一次大作业的过程中我已经通过之前的四次基础练习习题集基本熟悉和掌握了Java的基础语法知识,但对要求的其他知识体系如包装类和队列的使用仍很茫然,短时间只能由教材书上的代码示例大概了解其运用场景,对于其方法的交替和灵活使用基本无法做到,最后结合老师课程的讲解慢慢才熟悉了队列多数常用方法的基本使用。
第三是对问题的分析层面的问题。在第一次电梯作业中,最大的问题便是对于电梯运行过程本身的不理解和错误分析。虽然说老师已经为我们分析解答了电梯运行原理的调整以及关于其所含运行思想的声明(即方向优先,考虑队头等),但在实际算法实现的过程中常常结合代码实现无法理解给出的复杂输入输出样例中的运行结果,同时受到电梯LOOK算法的影响(资料查找)在代码编写细节中出现异常。

**当前实现代码问题分析**

对于当前迭代实现代码的结构中同时也存在着较多的细节和问题,在此基础上进行代码结构分析:

  1. 代码细节:该次实现代码行数共167行,由于此次单类程序设计,因而实现类行数共153行,主类代码行数共14行,程序代码总体设计上未超出老师预期的300行。

  2. 代码结构和内容主要问题:该段程序代码缺少一些必要的代码注释,在一定程度上影响了代码的可读性和维护性,尤其是对于电梯类中一些复杂的方法;在实现电梯类部分方法和主类主方法中存在高复杂度(如嵌套了多层条件分支语句),远超了SourceMonitor给出的推荐阈值,提高了不必要的空间复杂度;多个方法中存在着重复代码,相似度太高,不利于之后迭代扩展。

    类结构设计

第一次电梯程序类图如上,其中Main是主类,Elevator是电梯实现类,Direction是电梯运行状态枚举类。

2. 第二次迭代作业

**代码运行结果**

**问题层面分析**

在编写第二次电梯程序迭代作业时,老师给出了电梯调度程序的总框架类图,同时在第一次迭代问题的基础上增加了关于乘客请求错误及乘客请求不合理两种特殊情况的考虑。而在第一次迭代错误代码的失败总结后结合资料按照类图在第一次代码的基础上进行重写,最后截止前测试数据运行结果最后与预期结果后半段实现相差很大,其中存在着以下问题:
首先就心理状态相较于第一次已有较大改善,开始逐渐摆脱畏难心理尝试对电梯调度多类设计的每个类按照老师所给类图提示逐步实现,但在针对控制类“processRequest”、“move”、“shouldStop”三个关键方法实现时长时间停滞和实现错误,越接近截止时间心理状态就越无法保持平静,以致最后两个小时的时间放弃修改。
第二则是类间关系方面。第二次对于电梯调度程序的迭代作业中主要考查了关于电梯及乘客各主体之间的类关系细分及消息传递,即类间关系的设计。同时在实际问题中关于队列重复请求的处理,经截止时间之后与同学交流得知对于相同请求在实际实现中无需进行去重,但需同时处理相同楼层的内或外请求。对于处理类间关系时在考虑控制类上述三个算法与内外请求队列的消息传递时,难以明晰清楚该如何处理;在处理关键队列请求时,针对重复请求统一处理及算法要求的队头优先的原则产生思考角度的疑惑,感觉若统一处理重复请求在一定情况下违背了只考虑队头的原则。

**当前实现代码问题分析**

对于当前迭代实现代码的结构中同时也存在着较多的细节和问题,在此基础上进行代码结构分析:

  1. 代码细节:该次实现代码行数共209行,由于此次多类程序设计,程序代码总体设计上未超出老师预期的300行;在类间关系上按照老师给出的类图进行重写,基本符合类间关系要求和单一职责原则。

  2. 代码结构及内容存在问题:相较于第一次电梯调度算法程序代码,此次符合测试的覆盖率进一步下降;同时对于关键程序实现的注释依然缺少,影响之后对于代码的修改和维护;在代码块层面,部分方法的代码块的条件嵌套语句进一步增加,只是代码块深度增加,存在可读性问题及逻辑错误的潜在问题,而且对于后期的方法简化优化增加工作量。

    类结构设计

第二次电梯程序类图如上。其中“Direction”为电梯方向枚举类,“State”为电梯运行状态枚举类,“ExternalRequest”为外部乘客请求类,“RequestQueue”为请求队列类,“Elevator”为电梯类,“Controller”为控制类,“Main”为主类。

3. 第三次迭代作业

**代码运行结果**

**代码问题层面分析**

第三次电梯程序迭代作业延续了第二次迭代的类间关系设计思想,并进行了乘客请求类和队列类的设计合并,同时在输入和内外队列请求成员的实际运行转化做出了新的规定。而在第二次代码编写设计的基础上对相关类和类内算法进行重写和修改,最后在集成编译环境运行结果结合老师给出的输出样例相比较在实现结果的后半段存在不同,其中存在着以下问题:
1.核心类内运行算法问题:在第一次和第二次电梯对处理内外乘客请求的基础上对外部请求的后续处理进行了修改。经过老师上课讲解已经对电梯修改后的基本运行过程分析清楚,但对于内外请求的队头操作与队列整体对重复请求的判断和整体处理仍存在实现困难,同时对新增的队尾处理也存在着无法与其他方法形成合理的消息传递的问题,因而总是出现运行结果中对于部分楼层运行状态显示的丢失以及提前处理后续请求并显示电梯运行状态的问题。
2.类间关系消息传递问题:内外请求队列合并为队列类的类修改总体上对与控制类之间的关系及消息传递没有太大的改变,但对于新增的对于已处理的外部请求的队尾处理的方法安排,结合老师提供的类图猜测是对于“removeRequests”方法的修改,但是方法间的调用在思考处理时便出现了问题,以致在电梯运行时常出现重复楼层运行状态或运行结尾额外楼层输出。

**当前实现代码问题分析**

对于当前迭代实现代码的结构中同时也存在着较多的细节和问题,在此基础上进行代码结构分析:

  1. 代码细节:该次实现代码行数共189行,其中主类主方法共175行;在类间关系上按照老师给出的类图进行编写,基本符合类间关系要求和单一职责原则。

  2. 代码结构及内容存在问题:测试覆盖率相对于第二次程序有提升但仍然偏低,可能导致部分程序逻辑未被覆盖导致整体程序错误;“Elevator”类中的“update Direction”方法包含超多层嵌套循环,使方法逻辑上复杂度增大,影响了整体类及代码质量。

    类结构设计

第三次电梯程序类图如上。其中“Direction”为电梯方向枚举类,“State”为电梯运行状态枚举类,“Passenger”为乘客类,“RequestQueue”为请求队列类(对内对外请求),“Elevator”为电梯类,“Controller”为控制类,“Main”为主类。

三. 心路历程
初次面对电梯算法迭代作业时,我的心态可以用“如临深渊”来形容。题目集5~7的要求远超同题目集前两道基础练习,涉及复杂的算法设计等从未接触过的领域。尤其是第一次迭代作业最开始的时间,老师仅给出方向优先的算法思想,具体实现完全需要自行推导。我深知这是对编程能力的全面考验,但内心的畏难情绪一度占据了上风:面对陌生的队列操作、包装类使用和LOOK算法修改逻辑,我甚至怀疑自己是否能完成基础功能。这种心态直接影响了我的时间规划和代码质量。在第一次迭代中,我花费大量时间在反复调试输出结果与样例的细微差异上,却因缺乏系统性分析,最终放弃了对关键问题的修正。第一次提交后,我通过对比老师的样例输出和同学讨论,发现算法核心问题在于未正确处理请求队列的优先级。例如,在电梯运行过程中,未严格遵循“队头优先”原则,导致某些请求被提前处理。这一发现让我意识到:代码的缺陷往往源于对需求理解的偏差。
第二次迭代引入了多类设计(如“Controller”、“RequestQueue”等),类数量从3增加到7。尽管代码结构更符合单一职责原则,但新问题接踵而至:“Controller”类的“processRequests”方法需要协调电梯、队列、外部请求等多个对象,但因逻辑不清,常出现请求重复处理或丢失;部分方法的最大块深度达到5层(如“shouldStop”方法),代码可读性急剧下降;覆盖率进一步恶化:分支覆盖率从33.8%降至15.2%,新增逻辑几乎未被测试。在截止前的最后两小时,我尝试通过“暴力调试”定位问题,但最终因时间不足而放弃。这次失败让我深刻体会到:设计阶段的类图分析远比编码更重要。例如,未明确“ExternalRequests”和“RequestQueue”的交互规则,直接导致消息传递出现运行上的问题。
第三次迭代合并了内外请求队列,并优化了“Elevator.updateDirection()”方法。尽管代码行数减少至189行,但复杂度问题依旧突出: “updateDirection()”的复杂度在实际编写之后反增至16,包含多重循环和嵌套条件;代码块最大嵌套深度仍为5层,调试时需逐层展开逻辑,效率低下。
通过分析sourceMonitor的报告,我发现高复杂度的根本原因是职责未拆分。例如,“updateDirection()”同时承担了方向计算、请求校验、状态更新等多个任务,一定程度上复杂了类方法本身的职责。最终,在写blog期间我尝试将其拆分为calculateNextStep()和validateRequest()两个子方法,复杂度从16降至8。虽然程序依然未通过测试,但是这一改进让我理解了一点设计思路:代码质量的核心在于设计,而非功能实现。

四. 感悟
通过此次5~7次迭代性大作业,尽管最后依然没有完全通过测试点,但是依然从其中的程序编写以及知识学习中收获了一些,反思了许多。
经历此次迭代,我对这种较复杂实际编程工程从畏难逃避到主动分析,学会用工具(SourceMonitor)在编程测试分析后量化问题。我也一定程度上掌握了多类设计、复杂度控制、测试覆盖等编程时所要使用和注意的思想。
同时我也认识到了自身对于编程语言学习的落后和效率理解低下,以及对于所学技术的应用迟钝和僵硬,无法在需要的时候进行灵活变通,这也是我在三次迭代中不断失败的主要原因之一。
三次关于电梯程序的迭代作业暴露了从技术到心态的多方面的短板,虽然通过此次锻炼部分情况有所改善,但我知道还必须通过不断地学习和练习继续完善自我,不负自己的时间。