前三次作业总结
第一次作业
题目分析:
电梯属性管理:
维护最大 / 最小楼层、当前楼层、运行状态(停止 / 移动中)、运行方向(上行 / 下行 / 静止),以及内部请求队列(电梯内乘客目标楼层)、外部请求队列(电梯外乘客的楼层 + 方向)。
请求处理规则:
区分内部请求(仅楼层)和外部请求(楼层 + 上行 / 下行方向)。
处理无效请求(超出楼层范围的请求直接忽略)。
串行处理请求,无并发冲突。
运行调度规则:
默认初始状态为停在 1 层、状态静止、方向静止。
有请求时启动,优先处理同方向请求,同方向处理完毕再处理反方向。
每次移动 1 个楼层,到达楼层后检查是否有请求,有则开门→关门,再继续移动。
设计分析:
请求处理顺序:优先同方向,串行处理
核心依赖:队列的 "先进先出(FIFO)" 特性 +Direction()方法的方向决策逻辑。
实现逻辑:所有请求按输入顺序加入对应队列(内部 / 外部),保证串行处理(符合 "串行处理乘客请求" 要求)。
移动中时,Direction()方法会判断队首请求的楼层与当前楼层的关系:若队首请求楼层高于当前楼层→继续上行,低于则继续下行,确保同方向请求优先处理。
只有当队首请求处理完毕(从队列移除),才会处理下一个请求,间接实现 "同方向处理完毕再处理反方向"(例如上行请求全部处理后,队首出现下行请求,方向才会切换为 DOWN)。
开关门判断:精准匹配当前楼层的请求
Door()方法的判断逻辑分三层,覆盖所有请求组合场景:
同时有内部和外部请求:判断当前楼层是否同时匹配内部队首和外部队首(且外部方向与电梯方向一致),是则开关门并移除两个请求。
仅有内部请求:判断当前楼层是否匹配内部队首,是则开关门并移除该请求。
仅有外部请求:判断当前楼层是否匹配外部队首(且方向一致),或内部队列为空时匹配外部队首(此时可切换方向处理),是则开关门并移除该请求。
设计思路:优先处理 "同时命中内部和外部请求" 的场景,再分别处理单一队列请求,确保不遗漏任何需要停靠的情况。
输入解析:处理不同格式请求与无效输入
主类Main中的输入处理逻辑:
先读取最小楼层和最大楼层,初始化电梯实例。
用正则表达式<(.*?)>匹配请求格式,提取<>内的内容。
按逗号拆分提取的内容:
拆分后长度为 1→内部请求(仅楼层),转换为整数后调用addrequestin()。
拆分后长度为 2→外部请求(楼层 + 方向),转换楼层为整数后调用addrequestout()。
输入 "end"(不区分大小写)时终止输入,启动电梯运行。
无效输入处理:通过addrequestin()和addrequestout()中的楼层校验,自动过滤超出floorLow和floorMax的请求;格式错误的输入(未用<>包裹、方向非 UP/DOWN 等)会被正则匹配忽略,不加入队列。
类图设计:

SourceMonitor 报表分析:




Main.main()和elevator.Door()是高复杂度方法,是后续代码优化的重点
块深度分布:
深度 1~2 的块包含大量语句,说明代码存在较多 “单层 / 双层嵌套” 的合理逻辑
深度 4~5 的块仍有语句,但占比低,属于可接受的复杂分支
深度≥6 的块无语句,说明代码没有过度嵌套
其中深度 1~2 的语句占比最高,符合常规代码的结构特征;深度 5 是最大块深度,与Main.main()和elevator.Door()的复杂分支对应,整体嵌套层级在可维护范围内
Kiviat 图维度解读:
% Comments:9.1%,处于较低水平→需增加关键逻辑的注释。
Methods/Class:7.50→每个类(共 2 个类)平均包含 7.5 个方法,elevator类封装了多个核心方法
Avg Stmts/Method:6.80→多数方法(如FloormoveUP()、addrequestin())语句数≤3,仅少数方法(如main、Door())语句数多,整体平均水平合理。
Max Complexity:9→由Main.main()导致,需优化。
Max Depth:5→由Main.main()和elevator.Door()的嵌套逻辑导致,属于可优化范围。
Avg Complexity:3.38→多数方法复杂度低,仅个别方法拉高了平均值,整体复杂度可控。
Avg Depth:1.74→代码整体嵌套层级浅,可读性较好。
改进建议:
拆分Main.main():将 “输入解析”“正则匹配” 等逻辑提取为工具方法(如InputParser类),降低main方法的复杂度。
重构elevator.Door():将 “内部请求处理”“外部请求处理”“混合请求处理” 拆分为子方法(如handleInnerRequest()、handleOuterRequest()),减少分支嵌套。
第二次作业:
题目分析:
保留原电梯运行规则,并新增两个关键处理逻辑:
过滤无效楼层请求(超出最大 / 最小楼层);
过滤连续相同请求(避免重复处理)。
设计分析:
优先同方向处理:
电梯启动时,先确定当前方向(基于队首请求与当前楼层的关系),再找到该方向上最远的请求楼层。电梯向该楼层移动时,会逐一检查每层是否有匹配请求(内部请求或同方向外部请求),确保同方向顺路请求优先处理。
无效请求处理:
RequestQueue.addRequest() 中校验楼层是否在[minFloor, maxFloor]范围内,超出则直接忽略;
通过 PassengerRequest 的 equals() 方法判断,RequestQueue 不添加重复实例;
非法格式请求:Main 类中通过正则匹配和 try-catch 过滤(如非<>包裹、楼层非数字、方向非 UP/DOWN)。
输出格式合规:
ElevatorController.moveElevator() 中,每次移动后输出 Current Floor: X Direction: Y;
Elevator.openDoor()/closeDoor() 中直接输出对应日志,确保格式统一(如Open Door # Floor 3)。
类图设计:

SourceMonitor 报表分析:





Main.main()和RequestQueue.getFarthestSameDirectionFloor()是高复杂度方法,是后续优化的重点。
块深度分布:
深度 1~2 的块包含大量语句,说明代码存在较多 “单层 / 双层嵌套” 的合理逻辑。
深度 3~5 的块仍有语句,但占比低,属于可接受的复杂分支。
深度 7 是最大块深度,但仅 1 行语句,,整体嵌套层级在可维护范围内。
其中深度 1~2 的语句占比最高,符合职责拆分后代码的清晰结构;深度 7 的语句占比极低,说明没有过度嵌套”。
Kiviat 图维度解读:
% Comments:6.7%,处于较低水平→需在Main.main()、RequestQueue.getFarthestSameDirectionFloor()等复杂方法中补充逻辑说明。
Methods/Class:4.57→每个类平均包含约 4.5 个方法,因RequestQueue和ElevatorController封装了核心逻辑,方法拆分较合理。
Avg Stmts/Method:5.94→多数方法(如Elevator的moveUp()、PassengerRequest的getter)语句数≤5,仅少数方法(如main、getFarthestSameDirectionFloor())语句数多,整体平均水平合理。
Max Complexity:11→由Main.main()导致,需优化。
Max Depth:7→由Main.main()的嵌套逻辑导致,属于可优化范围。
Avg Complexity:2.50→多数方法复杂度低,,整体复杂度可控。
Avg Depth:1.96→代码整体嵌套层级浅,可读性较好。
改进建议:
拆分Main.main():将 “输入解析”“正则匹配” 等逻辑提取为工具方法(如InputParser类),降低main方法的复杂度。
重构elevator.Door():将 “内部请求处理”“外部请求处理”“混合请求处理” 拆分为子方法(如handleInnerRequest()、handleOuterRequest()),减少分支嵌套
第三次作业
设计分析:
优先同方向处理规则:
电梯当前有方向时,先通过hasRequestsInDir()判断同方向是否有未处理请求,有则保持原方向;
同方向无请求时,切换到相反方向,若相反方向有请求则更新方向;
电梯空闲(IDLE)时,通过findClosestRequest()找到最近的请求楼层,根据楼层高低确定初始方向。
外部请求转内部请求规则:
电梯停站后,遍历外部队列,找到 “源楼层 = 当前楼层 + 方向匹配” 的乘客;
将这些乘客从外部队列移除,同时以其 “目的楼层” 为目标,添加到内部队列(模拟乘客进梯后按下目标楼层);
后续调度中,内部队列的请求按 “目的楼层 + 同方向” 规则优先处理。
类图设计:

SourceMonitor 报表分析:




RequestQueue.hasRequestsInDir()是核心高复杂度方法,需通过逻辑拆分降低复杂度;Controller.determineDirection()和Main.main()的复杂度处于可接受范围。
块深度分布:
深度 1~2 的块包含大量语句,说明代码存在较多 “单层 / 双层嵌套” 的合理逻辑,符合职责拆分后的结构特征。
深度 3~4 的块语句占比降低,属于可接受的复杂分支。
深度≥5 的块无语句,说明代码无过度嵌套的 “迷宫式逻辑”。
其中深度 1~2 的语句占比最高,体现了职责拆分后代码的清晰结构;深度 4 是最大块深度,整体嵌套层级在可维护范围内
Kiviat 图维度解读:
% Comments:6.9%,仍需在RequestQueue.hasRequestsInDir()、Controller.determineDirection()等核心方法中补充逻辑说明。
Methods/Class:4.17→每个类平均包含约 4 个方法,RequestQueue和Controller封装了核心逻辑,方法拆分与职责匹配度高。
Avg Stmts/Method:4.68→多数方法(如Passenger的属性访问、Elevator的状态管理)语句数≤3,仅少数方法(如hasRequestsInDir()、main)语句数较多,整体平均水平合理。
Max Complexity:13→由RequestQueue.hasRequestsInDir()导致,需优化。
Max Depth:4→由Main.main()的输入解析逻辑导致,属于可优化范围。
Avg Complexity:2.05→多数方法复杂度低,仅RequestQueue.hasRequestsInDir()拉高了平均值,整体复杂度因类职责拆分而显著降低。
Avg Depth:1.54→代码整体嵌套层级浅,体现了职责拆分后逻辑的扁平化。
改进建议:
RequestQueue.hasRequestsInDir()优化:
将 “外部请求方向匹配” 和 “内部请求方向匹配” 拆分为hasExternalRequestsInDir()和hasInternalRequestsInDir()两个子方法,降低主方法的分支复杂度
Main.main()结构优化:
将 “输入解析” 逻辑提取为工具方法(如InputParser类),减少main方法的分支嵌套,降低其块深度和复杂度。
心得总结:
通过三次电梯调度程序的迭代开发,我对面向对象设计与单一职责原则(SRP)有了深刻的实践认知。
第一次作业中,我把所有逻辑都塞在一个类里,代码臃肿且难以维护;第二次作业尝试拆分类,将请求、队列、电梯、控制逻辑分开,明显感受到职责单一后代码的可读性和扩展性提升;第三次作业进一步细化数据模型,用Passenger类封装完整行程,让各模块的耦合度更低。这三次迭代让我明白,类的职责拆分不是越多越好,而是要精准匹配业务逻辑的边界。
浙公网安备 33010602011771号