BLOG-1
(一)前言:针对于前三次题目集,就难度来言对我来说实在是不小的,因为至今没有得到这第一次大作业的满分,只能拿到小题的分,对于电梯题目算法我并没有完美通过测试点,但是在前几个小题,以及对于电梯代码的不断调试过程中,我依然收获了一些先前所没有的内容,所以这次blog我分享的是一个总结性的博客。
我得到的知识点:
1.熟悉了JAVA语法
2.进一步加深了对于面向对象编程的了解
3.深刻认识到了代码可拓展性的重要性
针对于题量来说,并不多,但是很精,由此可见学校课程设计还是很用心的。
(二)设计与分析
首先先看第一次作业的电梯设计,因为我三次都没有得到电梯算法的分数。所以我多数分享的都是错误或者是不足,而且很多问题,至今仍然没有答案,希望有能者可以指点一二。
下图是第一次作业中给出的参考设计类图

分析这个类图
首先非常符合面向对象编程原则
通过组合(Controller 包含 Elevator 和 RequestQueue)、枚举(Direction/State)等,实现了高内聚、低耦合这一特点
后续需要新增功能时(如内部请求封装为InternalRequest类、更换调度算法为 “最短等待时间”),现有类结构可灵活调整。
实现电梯调度,核心模块分工:
枚举类(Direction/RequestType):定义电梯方向和请求类型;
数据类(PassengerRequest):封装乘客请求(楼层 + 类型);
队列管理(RequestQueueManager):维护内部 / 外部上行 / 外部下行三类请求队列;
电梯实体(Elevator):管理电梯当前楼层、方向、移动逻辑;
调度算法(ElevatorScheduler):基于扫描算法确定电梯下一个方向;
控制器(ElevatorController):串联所有模块,控制电梯运行流程;
输入解析(InputParser):解析用户输入的请求格式
在这第一次作用中,我有一个最严重的错误出现在ElevatorController.runElevator() 中「移动电梯」与「检查停靠」的顺序反了。这就导致了代码出现了严重的逻辑错误,正确的电梯代码逻辑应该是:移动电梯 → 检查是否停靠 → 处理请求
但是我的代码中逻辑顺序是:检查是否停靠(处理请求) → 移动电梯
这使得代码运行正常,但是结果出现错误,电梯初始楼层的请求无法处理(例如电梯初始在 1 楼,有请求<1>,会直接移动到 2 楼,跳过 1 楼);
当前楼层的请求被忽略(例如电梯在 3 楼,有请求<3>,会先移动到 4 楼再检查,3 楼请求永远未处理);
部分请求陷入「队列非空但电梯无法响应」的死循环。不出意外,代码出现了超时的情况,因为有一部分测试点陷入了死循环
接下来这个错误是因为没有考虑到实际情况
错误位置:ElevatorScheduler.determineNextDirection()
当所有请求都在电梯当前楼层时(例如电梯在 3 楼,请求<3>),hasRequestsAbove()和hasRequestsBelow()均为false,调度器会返回IDLE。这个情况下,队列仍然没有情空,但是电梯已经停止运行了,使得后续无法操作,出现结果错误
再来看第二次电梯的设计和分析
先看类图
这次的要求是对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP)
明确请求的 “来源 + 方向” 属性,为 RequestQueueManager 的队列分类管理、ElevatorController 的停靠判断提供依据。
该类图是一个单电梯调度系统 结构如下:

这是给出的要求:
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
关于我这第二次的代码首先,我自己设计的核心业务流程包括如下:
输入解析:Main 读取楼层范围和请求,InputParser 解析为 PassengerRequest 实例;
请求入队:ElevatorController 验证请求有效性后,通过 RequestQueueManager 分类存入对应队列;
电梯启动:ElevatorController 调用 ElevatorScheduler 确定初始方向;
循环运行:电梯按方向移动 → 检查当前楼层是否有可处理请求 → 停靠(开门 / 删请求 / 关门)→ 重复,直到无请求;
空闲状态:无请求时电梯停在当前楼层,方向设为 IDLE。
由于这第二次作业我当时并没有发现顺序错误的问题,所以依然犯了和第一次代码一样的错误
ElevatorController.runElevator() 中「移动电梯」与「检查停靠」的顺序错误:
错误逻辑:移动电梯 → 输出位置 → 检查是否停靠(处理请求)
正确逻辑:检查是否停靠(处理请求) → 移动电梯 → 输出位置 问题位置
RequestQueueManager.removeRequestsAtFloor(int floor):删除指定楼层的所有请求,未区分请求类型与电梯当前方向。电梯上行到 5 楼,处理 UP 请求(删除 UP 队列),DOWN 请求保留,后续下行时处理;
实际结果:
电梯上行到 5 楼后,调用 removeRequestsAtFloor(5),同时删除 UP 和 DOWN 请求,DOWN 请求永久丢失。电梯上行到 5 楼,处理 UP 请求(删除 UP 队列),DOWN 请求保留,后续下行时处理;
这就导致外部同一楼层的反向请求被误删,导致部分乘客永远无法被响应,违背电梯运行逻辑。
这是我用AI出来的问题输入异常未处理:Main 中读取楼层时,若输入非整数(如 a),会抛出 NumberFormatException,程序直接崩溃;
队列查询效率低:hasRequestsAbove()、getHighestRequestFloor() 等方法调用 getAllRequests(),重复遍历 3 个队列(时间复杂度 O (n));
外部请求判断冗余:hasRequestAtFloor() 用 for 循环遍历队列,可简化为 stream 表达式;
批量请求处理限制:代码仅支持 “一次性输入所有请求”,不支持动态添加请求(现实中电梯需实时响应新请求)。
第三次代码,是最复杂的一次,调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制
对于这次的乘客类,我的理解是核心定位
本质:纯数据载体(DTO),仅存储请求相关信息,不包含业务逻辑
作用:将 “乘客要去的楼层” 和 “请求类型(内部 / 外部上下行)” 绑定,让后续队列管理、调度算法能直接基于该类做逻辑判断。构造方法:强制创建请求时必须指定floor和type,避免无效请求
Getter 方法(getFloor()/getType()):保证属性只读,防止外部随意修改请求信息,符合封装原则;
toString():格式化请求字符串(如<3,UP>/<5>),方便日志输出和调试。
解耦:隔离乘客请求数据与调度、队列等业务逻辑,后续扩展请求属性(如优先级、时间戳)无需修改核心业务代码;
标准化:统一请求格式,让输入解析、队列存储、调度判断有统一的操作依据(如外部上行请求必须关联EXTERNAL_UP类型)。
在这一基础上增加关于乘客的部分,这次我尝试过但是完全没法实现
(三)总结
(一)类设计必须坚守 “单一职责原则”,拒绝 “万能方法”
RequestQueueManager 的 removeRequestsAtFloor 方法之所以出错,本质是将 “删除当前方向相关请求” 的单一职责,扩展为 “删除所有请求” 的全能职责,导致操作粒度与业务需求脱节。修复后新增的 removeRelevantRequests 方法,仅聚焦 “当前方向 + 指定楼层” 的请求删除,职责明确,无冗余操作。心得:类的每个方法应只做 “一件与业务强相关的事”,方法名与功能必须严格对齐(如removeRelevantRequests 直接体现 “移除相关请求”),避免因职责模糊导致逻辑错误。
(二)流程设计必须遵循 “先判断后执行”,杜绝 “动作先行”
ElevatorController 的核心错误是 “先移动电梯,后检查请求”,违背了 “先确认状态,再执行动作” 的工程逻辑。电梯作为物理实体,必须先判断当前楼层是否需要停靠,再决定是否移动 —— 这与现实世界的电梯运行逻辑完全一致。心得:核心业务流程设计前,应先梳理 “状态判断节点” 与 “动作执行节点” 的顺序关系,可通过流程图可视化验证,避免因逻辑倒置导致核心功能失效。
(三)边界场景是 “源码健壮性的试金石”,必须全覆盖
调度器未处理 “仅当前楼层有请求” 的边界场景,导致 2 组测试用例失败。这类场景在实际使用中占比不高,但一旦出现会直接导致功能瘫痪。修复后通过新增 “当前楼层请求判断”,补全了调度算法的逻辑闭环。心得:提交源码前,需设计 “核心路径 + 边界场景 + 异常输入” 三类测试用例,其中边界场景应包括 “无请求、仅当前楼层有请求、同一楼层多请求” 等极端情况,确保逻辑无死角。
(四)异常处理是 “用户体验的底线”,必须隔离非法输入
Main 类未处理非整数输入、无效楼层范围等异常,导致程序直接崩溃。修复后通过 try-catch 捕获异常并提示用户重新输入,实现了 “非法输入隔离”,确保核心逻辑不受影响。心得:所有与用户交互的模块(如输入处理、请求解析)都必须添加异常捕获机制,将非法输入拦截在核心逻辑之外,同时给出明确的错误提示,提升程序可用性。
(五)提交前必须执行 “四维检查清单”,避免低级错误
类方法维度:每个方法的职责是否单一?操作粒度是否匹配业务需求?
流程步骤维度:“判断 - 执行” 顺序是否正确?是否符合现实逻辑?
边界场景维度:是否覆盖 “无请求、仅当前状态、多冲突请求” 等场景?
异常处理维度:是否对输入、数据转换、边界值等可能出现异常的地方做容错?
代码出现的核心问题并非复杂的算法缺陷,而是类设计职责不清晰、流程逻辑倒置、边界场景缺失等 “基础设计问题”,但这些问题直接导致核心功能失效,影响范围覆盖 80% 的测试场景。通过针对性修复(调整流程顺序、拆分方法职责、补全边界判断、添加异常处理),程序从 “不可用” 变为 “完全可用”,验证了 “基础设计决定系统稳定性” 的核心原则。

浙公网安备 33010602011771号