电梯调度总结分析

一:前言 :电梯调度的程序设计问题第一次放出来我就一点头绪都没有。直到看到老师给的类图以及Main方法我才能照着进行编写。但是很遗憾,我的所有编写都是止步于IDEA的调试。根本没有完全成功编写成功过。第一次的电梯程序作业主要考察我们对类与对象创造的理解,即面向对象的思维。并且将不同的类放到不同的文件中(这一点在C语言中一致)。在对象的创建中我学会了将对象的方法一起附在其中,比如电梯是自己Show自己。而后两次电梯的迭代中,告诉我们要将算法当中的步骤按更小的模块依次分析,这样才方便在类的调整中重新改写方法之间的调用关系。提高程序的复用性。使其更好实现单一职责、职责更完善。
二.设计与分析:
题目1:设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求)。
附类图:
类分析:

  1. ​​Request类​​
    ​​功能​​:表示电梯的请求指令,包含目标楼层和方向。
    ​​属性​​:
    dir: String(请求方向,如"UP"/"DOWN")
    floor: int(目标楼层)
    ​​方法​​:
    构造方法:默认构造和带参数的Request(String dir, int floor)。
    访问方法:setDir(), getDir(), setFloor(), getFloor()。
  2. ​​Elevator类​​
    ​​功能​​:管理电梯状态、处理请求及执行移动逻辑。
    ​​属性​​:
    currentFloor: int(当前楼层)
    direction: String(运行方向)
    status: String(状态,如"MOVING"/"IDLE")
    maxFloor/minFloor: int(可到达的楼层限制)
    internalRequest: Request(当前处理的请求)
    ​​方法​​:
    构造方法:支持初始化楼层限制。
    请求管理:addRequest()添加请求,isEmpty()检查请求队列。
    其他方法:move()逐步移动,openAndPrint()开门并显示状态,moveToFloor()直接跳转楼层。
    ​​关键逻辑​​:
    电梯需根据请求的方向和楼层排序处理(如优先处理同方向请求)。
    通过printFloor()实时反馈位置,setDirection()更新运行方向。
  3. ​​Main类​​
    ​​功能​​:程序入口,启动电梯系统。
    ​​方法​​:main()方法初始化电梯对象并模拟请求。
    第一次的源码分析:

题目2与1类似只是多出了几个类,但是电梯使用了LOOK算法。经过搜索我才了解LOOK算法。LOOK算法核心即是先进先出。优先处理命令队列里的第一个命令。
下面是类图展示:

源码分析:

第三次电梯:
类图展示:

较前一题需要我们加入乘客类(Passenger),删去请求类。要求也有变动:乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
类关系展示:
类分析​​
​​Direction(方向枚举)​​
​​定义​​:UP(上行)、DOWN(下行)、IDLE(静止)
​​作用​​:描述电梯当前运行方向或静止状态。
​​关键关联​​:被Elevator类的direction属性直接引用。
​​State(状态枚举)​​
​​定义​​:MOVING(移动中)、STOPPED(停止开门)、IDLE(空闲)
​​作用​​:描述电梯的实时运行状态。
​​关键关联​​:被Elevator类的state属性引用。
​​Elevator(电梯类)​​
​​属性​​:
currentFloor(当前楼层,int)
direction(方向,Direction枚举)
state(状态,State枚举)
maxFloor/minFloor(最大/最小楼层,int)
​​方法​​:
move():控制电梯移动,根据方向更新楼层。
openDoors():开门并更新状态为STOPPED。
isValidFloor(int):验证目标楼层是否合法。
​​关联关系​​:
双向关联Controller:通过controller属性实现双向通信。
​​Controller(控制器类)​​
​​属性​​:
elevator(控制的电梯实例)
queue(请求队列)
​​方法​​:
processRequests():核心调度方法,处理所有请求。
determineDirection():根据请求动态调整电梯方向。
shouldStop(int):判断是否在指定楼层停止。
​​关联关系​​:
聚合Elevator和RequestQueue:管理电梯和请求队列的生命周期。
​​Passenger(乘客类)​​
​​属性​​:
sourceFloor(起始楼层,Integer,可为null)
destination(目标楼层,Integer)
​​方法​​:
构造函数:初始化起始和目标楼层。
getSourceFloor()/getDestination():属性访问方法。
​​关联关系​​:
被RequestQueue聚合:乘客请求存储在队列中。
​​RequestQueue(请求队列类)​​
​​属性​​:
internalRequests:内部请求队列(乘客在电梯内按下目标楼层)。
externalRequests:外部请求队列(乘客在楼层按下上行/下行按钮)。
​​方法​​:
addInternalRequest(Passenger):添加内部请求。
addExternalRequest(Passenger):添加外部请求。
removeRequests(int):清除与当前楼层相关的请求。
getNextRequest():获取下一个待处理请求。
源码分析:



我学到了啥:
(1)Main 直接参与系统初始化
(2)Direction 枚举包含 IDLE,而 State 也有 IDLE,,增加了调试难度
(3)State 和 Direction 存在逻辑重叠(如 IDLE 状态需强制 direction=IDLE)
(4)请求处理复杂多样,程序需要很多if语句判断不同情况
(5)最好可以实现请求优先级。但是太难了啊
三:改进:
1.​​单一职责原则​​:每个类只做一件事(如拆分Controller)
2.​​开闭原则​​:通过扩展而非修改实现新功能
​​3.依赖倒置​​:高层模块不依赖低层细节
​​4.防御性编程​​:对输入参数进行严格校验(如楼层合法性检查)
四:收获:
​​面向对象设计能力提升​​
1.深刻理解了 ​​单一职责原则​​ 的重要性,学会通过合理拆分类与方法来降低代码耦合度
2.掌握 ​​开闭原则​​ 实践技巧,能通过扩展而非修改应对需求变更(如新增电梯状态类型)
3.强化 ​​状态模式​​ 和 ​​策略模式​​ 的应用能力,实现电梯状态机与调度算法的灵活解耦
​​算法与数据结构实战经验​​
1.在实现LOOK调度算法过程中,提升了对 ​​双向队列​​ 和 ​​优先级队列​​ 的理解与应用能力
2.通过请求队列管理,熟练掌握了 ​​链表操作​​ 和 ​​集合过滤​​ 的高效实现方式

posted on 2025-04-20 23:14  不要尔康  阅读(42)  评论(0)    收藏  举报