题目集 5~7 总结性博客
一、前言
题目集 5 至 7 涵盖了丰富的知识点,包括面向对象编程中的类设计、正则表达式的应用以及复杂的算法逻辑(如单部电梯调度)。题量上,每次题目集均包含多道题目,难度呈梯度上升。题目集 5 侧重基础,如正则表达式校验(如验证码、QQ 号校验);题目集 6 引入复杂逻辑,单部电梯调度问题需综合考虑请求队列管理、电梯运行方向与状态控制;题目集 7 进一步深化类设计,如汽车风挡玻璃雨刷问题、平面直角坐标系点与线的类设计等。这些题目集不仅检验对知识点的掌握,还锻炼了逻辑思维与代码实现能力。以下分析以电梯为例。
二、设计与分析
题目集5未要求类设计,代码设计如下:
1.Main 类 - main 方法:先读取最小楼层 minfloor 和最大楼层 maxfloor,然后循环读取输入,通过正则表达式 reg1(<\d+,(UP|DOWN)>,匹配外请求)和 reg2(<\d+>,匹配内请求)验证输入格式,同时检查请求楼层是否在 [minfloor, maxfloor] 范围内,合法的存入 require 列表,直到读取到 end 结束输入。接着设置电梯的最大、最小楼层及请求列表 require,调用 isInnerOrOuter 区分内外请求,分别存入 InnerQueue(内请求)和 OuterQueue(外请求),再调用 elevator.action() 启动电梯调度逻辑。
2. Elevator 类 - isInnerOrOuter 方法:遍历 require 列表,根据字符串是否包含逗号区分内外请求:含逗号的(外请求)加入 OuterQueue,不含逗号的(内请求)加入 InnerQueue。
3. Elevator 类 - action 方法:初始化当前楼层 floorNow = 1,然后在 InnerQueue 或 OuterQueue 不为空时持续循环。当内外队列均非空时,先处理同楼层请求的情况,若方向为 IDLE 则根据楼层与当前楼层关系设方向,处理后移除两个队列的首个元素;若方向为 IDLE,还需判断内外请求是否在当前楼层同一侧(同大于或同小于 floorNow),同一侧时比较内外请求与当前楼层距离来优先处理,不同侧也优先处理距离近的请求;若方向为 UP 或 DOWN,则分别按对应方向的规则处理请求(如外请求楼层符合方向且位置合适则优先处理外请求,否则处理内请求或设方向为 IDLE)。当仅外队列空时处理内队列首个请求,仅内队列空时处理外队列首个请求。最后调用 printOutput 输出结果。
4. Elevator 类 - elevatorAction 方法:根据方向 UP 或 DOWN 循环记录楼层状态,最后添加开门、关门操作的输出。printOutput 方法遍历 output 列表,按规则输出(最后一条记录不换行,其余换行)。整个代码通过输入验证、内外队列区分、复杂的条件判断实现电梯调度,action 方法虽覆盖多种调度场景(如同楼层请求、方向切换、内外队列优先级),但多层 if - else 嵌套导致逻辑复杂,可读性与维护性较差,测试时需覆盖不同请求顺序、方向组合等场景以确保调度逻辑正确。
5.Elevator 类 - printOutput 方法: 遍历 output 列表,按规则输出(最后一条记录不换行,其余换行)。
题目集6,类图设计如下:
- Elevator 类
Elevator 类用于表示电梯实体并管理其状态与属性。该类包含 currentFloor 表示当前楼层、direction 表示运行方向(取值如 IDLE、UP、DOWN)、state 表示状态(如 STOPPED、MOVING ,代码中状态切换体现不完全),以及 maxFloor 和 minFloor 表示电梯运行的最大和最小楼层等属性。其方法包括构造函数 Elevator (int minFloor, int maxFloor) 用于初始化电梯,默认当前楼层为 1,方向为 IDLE,状态为 STOPPED;一系列 getter/setter 方法用于获取或设置电梯属性;isValidFloor (int floor) 方法用于检查楼层是否在 [minFloor, maxFloor] 范围内;floor (String str) 方法用于从输入字符串(如 < 3 > 或 < 4,UP>)中解析楼层值。 - ExternalRequest 类
ExternalRequest 类的职责是表示外部请求,如楼层外的呼叫。该类拥有两个属性,分别是 floor 表示请求的楼层,direction 表示请求的方向(取值如 UP、DOWN)。其方法包括构造函数 ExternalRequest (Integer floor, String direction),用于初始化请求;还有获取楼层的 getFloor 方法和获取方向的 getDirection 方法;并且重写了 equals 和 hashCode 方法,以此保证相同楼层和方向的请求会被视为同一个请求。 - RequestQueue 类
RequestManager 类的职责是管理电梯的内外部请求队列。该类具有两个属性,internalRequests 表示内部请求队列,其为用户在电梯内选择的楼层列表;externalRequests 表示外部请求队列,是楼层外呼叫的 ExternalRequest 对象列表。其方法包含 addInternalRequest (int floor),用于添加内部请求,并且不会重复添加相同楼层;addExternalRequest (int floor, String direction) 用于添加外部请求,同样不会重复添加相同的请求;还有一系列 getter/setter 方法,例如 getInternalRequests 用于获取内部请求队列、setExternalRequests 用于设置外部请求队列,以此来实现对电梯内外部请求队列的获取和设置操作。 - Controller 类
ElevatorController 类的职责是控制电梯运行并处理请求队列。该类有两个属性,elevator 是关联的电梯对象,queue 是请求队列对象。其核心方法包括:processRequests () 作为主逻辑,会循环处理内外部请求,依据电梯当前方向和请求楼层来决定移动路径,进而调用 move 方法模拟电梯移动;move (int startfloor, int endfloor, String direction, ArrayListoutput) 会按照方向(UP 或 DOWN)更新楼层,记录移动日志,同时调用 openDoors 方法处理开门和关门操作;openDoors (ArrayList output, int endfloor) 用于添加开门(Open Door # Floor % d)和关门(Close Door)的日志;removeRequest (int innerFloor, ExternalRequest outerReq) 可从队列中移除已处理的内部或外部请求;printOutput (ArrayList output) 用于打印最终的电梯运行日志。 - Main 类
Main 类作为程序入口,负责处理输入并初始化系统。其逻辑为:首先读取 minfloor 和 maxfloor 的值,依据这些值创建 Elevator 对象和 RequestQueue 对象;接着进入循环读取输入内容,将输入解析为内部或外部请求,并添加到对应的请求队列中,当输入 “end” 时,循环结束;最后创建 Controller 对象,并调用其 processRequests () 方法来启动电梯控制逻辑。
三、采坑心得
在源码提交过程中,遭遇了若干问题,以下从数据、类设计结构、流程图及测试结果等方面展开总结:




• 类设计结构问题:Controller 类中的 processRequests 方法逻辑过于复杂,从 Metrics Details 可见,类似 Elevator.action() 方法复杂度高达 37,这使得代码可读性与维护性极差。例如,在处理内外部请求混合的场景时,方向判断与楼层移动逻辑交织,导致调试困难。
• 请求处理逻辑缺陷:RequestQueue 的请求去重机制不够完善。测试中发现,重复添加相同内部或外部请求时,未做有效过滤,如连续添加楼层 3 的内部请求,代码未进行去重处理,影响电梯运行效率与逻辑正确性。
• 复杂场景处理混乱:当内外请求同时存在且方向冲突时,电梯运行逻辑出错。如输入内部请求 3,外部请求 2(方向 DOWN),电梯方向判断失误,未按合理逻辑运行。分析类图与流程图可知,Controller 类在协调 Elevator 与 RequestQueue 时,复杂场景下的协作逻辑不够清晰,导致决策失误。
(4)改进建议
• 方法拆分与简化:将 Controller 中 processRequests 方法拆分为多个小方法,如 determineDirection(方向判断)、moveElevator(移动逻辑)等,降低方法复杂度,提升可读性。参考类图,可在 Elevator 类中增加更多状态处理方法,如 updateState 专门处理状态转换。
• 优化请求队列:RequestQueue 内部使用 HashSet 替代 LinkedList 处理请求,确保请求唯一性,避免重复处理。例如,添加内部请求时,通过 HashSet 的特性自动去重,提升代码效率与健壮性。
• 增强日志与调试:在关键逻辑点(如方向改变、楼层移动)添加日志输出,便于追踪问题。例如,在 move 方法中记录详细的移动轨迹,为后续调试与功能扩展提供便利,实现代码的可持续改进。
五、总结
学习收获:通过三次题目集的实践,对面向对象设计的理解从理论层面深化到工程实践。以电梯调度为例,通过Elevator类封装电梯状态(当前楼层、运行方向、有效楼层范围)与基础操作(楼层校验、状态更新),Controller类专注于调度逻辑,体现了 “单一职责原则”,避免代码臃肿。在题目集 7 的汽车雨刷系统设计中,尝试通过继承实现不同雨刷模式(如低速、高速、间歇模式),利用多态统一处理雨刷动作,初步掌握了抽象类与接口的实际应用。正则表达式的学习则在题目集 5 的输入校验中得到充分锻炼,例如 QQ 号校验通过正则表达式[1]\d{4,14}$精准匹配 5-15 位数字且不以 0 开头的规则,学会了通过边界值测试(如刚好 5 位、15 位的输入)确保校验逻辑的严谨性。最具挑战性的电梯调度问题中,通过设计内外请求队列、实现顺向优先调度策略,深入理解了复杂算法的分层实现 —— 从请求解析(字符串处理与合法性过滤)到核心调度(方向决策与路径规划),再到日志生成(严格遵循输出格式),每一步都需要逻辑的严密性与代码的模块化。
需加强部分:尽管完成了题目要求,但在算法优化与复杂类设计上仍有明显提升空间。电梯调度中,当前的请求处理逻辑采用基础的顺序遍历队列,在大量请求场景下效率较低,未来可探索使用优先级队列(如根据距离当前楼层的远近排序)或引入经典调度算法(如 SCAN 算法)来减少电梯空驶时间,提升代码效率。在题目集 7 的雨刷系统设计中,初期对类属性的抽象不够精准,例如将雨刷的 “摆动频率” 与 “工作状态” 混杂在同一个类中,导致方法逻辑冗余,后期通过拆分WiperMode枚举类(定义不同工作模式)和WiperController类(管理状态切换)才逐步理清结构。这表明在面对复杂业务场景时,需要更深入地分析对象的职责边界,避免属性与方法的过度耦合,提升类设计的抽象能力。
对课程建议:增加代码规范示例,讲解优秀代码结构。实验课增加互动环节,针对常见错误集中讲解。提供更多拓展学习资源,如设计模式在实际项目中的应用案例,助力深入理解面向对象编程。
通过这三次题目集,不仅巩固了编程知识,更锻炼了分析与解决复杂问题的能力。未来将继续加强实践,提升代码质量与逻辑思维能力。
1-9 ↩︎

浙公网安备 33010602011771号