单部电梯调度题目集总结
单部电梯调度题目集总结
前言
作为一名刚接触面向对象编程的大一生,这三次电梯调度作业对我来说既充满挑战又收获颇丰。刚拿到题目时,看着“内部请求”“外部请求”“同向优先”这些陌生词汇,顿感压力倍增。
我第一次作业时,我天真地以为只要把请求塞进队列、让电梯按顺序处理就行,结果空队列死循环折磨得焦头烂额。到了第二次作业,原本想通过新增Controller类让代码更清晰,没想到方向判定逻辑的混乱反而让电梯像无头苍蝇一样乱撞。直到第三次作业引入职责分离和模块化设计,才终于体会到“代码优雅”的成就感——虽然最后也没拿多少分,但至少有所进步,领悟到了一些面向对象的感觉。
第一次作业:
作业要求
实现单部电梯基础调度功能,涵盖内部请求(格式如<1>)与外部请求(格式如<2,UP>),电梯具备运行方向属性,停梯时优先处理同方向请求。
实现方式
核心架构:构建Elevator类承载运行逻辑,Main类借助正则解析输入,InnerQueue、OuterQueue类分别存储内外请求。
方向判定:determineDirection方法依据当前楼层及请求列表确定电梯运行方向,停梯时按优先级处理同方向请求。
正则解析:运用innerPattern = "<(\d+)>"与outerPattern = "<(\d+)\s,\s(UP|DOWN)>"区分不同请求类型,虽初觉正则便捷,但编写时对空格、大小写规范存顾虑。
代码规模
第一次作业代码规模如下图

类图
第一次作业类图如下

核心类:
Main:程序入口,依赖Elevator
Elevator:管理电梯状态(currentFloor, direction)及请求队列(InnerQueue/OuterQueue)
FloorRange:楼层范围校验(isValid())
复杂度分析
SourceMonitor 显示Elevator类processRequests及determineDirection方法环路复杂度较高。归因于方向判断内堆叠诸多if-else语句,停梯需判别未处理请求,上行时要审视上方同向请求,逻辑未拆分,致使方法臃肿。
Bug 分析
公测:顺利通过。然而互测时,输入如<3 , DOWN>(含多余空格)未识别,因正则\s*考虑不周,未预见用户输入或含多个空格的边界情况。
自测问题:输出未考量请求队列为空场景,电梯停驻某层且内外请求全处理完时,代码未判定,致电梯空转,耗费较长时间排查此逻辑疏忽。
测试方法
手动编写多类输入用例,如边界楼层(1 楼、最高层)、混合请求(先上后下)
第二次作业:
作业要求
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
实现方式
新增Controller类:统筹乘客请求,将外部请求(起点加方向)与内部请求(终点)整合为PassengerRequest对象。
停梯逻辑:shouldStop方法同步核查内外请求,电梯上行时,若外部请求位于当前楼层下方且方向为 UP,需判定是否顺路停梯,逻辑制定时混乱,致使停梯失误。
代码规模
第二次作业的代码规模如下图。

类图
第二次作业类图如下

新增类:
InternalRequest(目标楼层)与ExternalRequest(呼叫方向)
PassengerRequest组合两者,表示完整乘客请求
复杂度分析
shouldStop方法环路复杂度极高,因要权衡同向、反向请求优先级,如外部请求在电梯下方、方向 UP,电梯上行时是否顺路停靠,逻辑分支繁多且未拆分方法,复杂度失控。
Bug 分析
方向判定偏差:电梯上行时错误处理下方 DOWN 外部请求,违背同向优先原则,经同学互测指出后,意识到逻辑合理性不足。
集合操作失误:以HashMap存外部请求时,remove方法失效,因未重写请求类equals和hashCode方法,致按地址判等,请求无法移除。
测试方法
尝试编写简单对拍器,借助 Python 生成请求序列模拟运行,但对复杂请求组合覆盖不足,多数 bug 依赖互测极端用例发现。
第三次作业:
作业要求
对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类
电梯运行规则与前阶段相同,但有如下变动情况:
乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
重构代码,强化模块化与可维护性,以枚举定义方向,分离请求管理与电梯执行逻辑,如ElevatorController负责调度,Elevator类仅处理移动与停梯。
实现方式
职责分离:ElevatorController处理请求队列、决策方向与停梯;Elevator类仅留moveUp、moveDown、stop等基础方法,实现高内聚低耦合。
枚举运用:定义Direction枚举(UP/DOWN/STOP),替代原字符串判断,提升代码可读性与稳定性。
代码规模
第三次作业的代码规模如下图。

类图
第三次作业类图如下

结构升级:
新增ElevatorController:独立处理请求队列(processRequests())和方向决策
Passenger类:明确乘客实体,可发起外部请求(ExternalRequest)
复杂度分析
各方法复杂度显著降低,因拆解为processInternalRequests、processExternalRequests等小方法,处理外部请求时,仅电梯达源楼层且方向适配时才转为内部请求,逻辑分块,条理明晰。
Bug 分析
请求转换时序错位:初始未在电梯抵达外部请求楼层时及时转换请求,致请求堆积,电梯持续携带未处理外部请求运行,经打印请求队列排查。
边界值疏漏:依赖自动生成数据测试,漏测楼层最大值(如题目上限 20 楼,误写为<20>),手动构造特定请求才发现问题。
测试方法
手动构造边界值、异常输入(如非法字符
三次作业共性问题剖析与反思
- 正则表达式应用
第一次未妥善处理空格,第二次忽视大小写,直至第三次封装InputValidator类专注输入格式规范,方领悟正则严谨性对程序健壮性关键意义。 - 复杂度管控
前两次作业逻辑过度集中于processRequests方法,致代码冗长、嵌套过深。第三次通过拆分小方法,遵循 “单一职责原则”,有效控制复杂度。 - 测试策略优化
第一次纯手动测试,第二次依赖自动生成,第三次融合两者,自动化测常规场景,手动测边界与异常,如第三次请求转换逻辑需特定顺序手动构造用例验证。 - 面向对象设计深化
从首次将逻辑堆砌于Elevator类,到二次组合请求类,再到三次分离职责,领悟封装精髓。ElevatorController专注 “决策去哪”,Elevator专司 “如何行动”,修改调度策略与电梯执行代码互不干扰,拓展性飞跃。
典型错误复盘:
第一次作业
低估正则表达式对输入格式适配性要求,未全面考量多余空格、大小写等变体,后续输入解析严守格式规范。
第二次作业
方向判断脱离 “同向优先” 原则,依赖直觉编写逻辑,致电梯运行无序。经流程图梳理请求处理流程,方规范决策逻辑,深感流程图辅助复杂逻辑梳理之效。
第三次作业
过度信赖自动测试,忽视边界值手动验证,栽于楼层最大值判定失误。此后时刻留意保留手动测试用例,专攻边界条件检测。
改进:
输入输出封装:构建独立InputParser、OutputFormatter类,Main类仅负责程序启动,降低模块耦合度,提升输入格式变更适应性。
测试用例沉淀:建立 Excel 表格归档各作业边界值、异常输入、复杂请求组合,形成测试用例库,避免重复构思,提升测试效率。
代码可读性强化:为复杂方法配置详尽注释,采用更具表意性的变量命名,便利代码阅读与维护。
结语:
通过三次电梯调度作业的实践,我深刻体会到软件工程中架构设计与代码质量的重要性。从初期面向过程思维的惯性到逐步领悟面向对象设计原则,这一过程不仅是对编程能力的锤炼,更是一次思维模式的升级迭代。
在架构演进方面,初次作业暴露了功能耦合的弊端,电梯类承载过多职责导致逻辑复杂度失控;第二次作业通过引入控制层解耦请求管理,却在集合操作与方向判定上产生新隐患;最终作业采用模块化设计策略,将调度决策、请求转换、移动执行等功能拆分为独立模块,使系统扩展性显著提升。
由于我前期的不重视,导致后面的代码迭代过程非常痛苦。这个教训让我明白了很多:面向对象程序设计并不是随便学学就能应付的,确实是要花时间,花心思去学习。下次大作业希望能好好安排时间完成大作业任务。

浙公网安备 33010602011771号