blog

一.前言 本次电梯题目创新新颖,难度层层递进,环环相扣,在迭代的基础上增加不同方法,我认为是一次能力的提升与检测,虽然执行过程中出现小瑕疵有时与测试点不符合。但还是一次对自身编程能力的挑战。在此期间我哦自主学习了正则表达式与队列并收获了许多有用的思维。该大作业难度适中,起到了很好的过度作用。
二.

第一次电梯:设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式
分析图:
第一题复杂度较低,主要踩坑点在于未能够准确理解题目所表达的逻辑且测试点较少无法准确掌握逻辑,但好在后续因为此问题老师提供了main函数和类图方能顺利通过。
该程序存在单一职责原则违背:Elevator 类承担了过多的职责,既负责电梯状态管理,又处理请求队列管理和调度算法,这违反了单一职责原则,使得代码的可维护性和可扩展性变差。若要修改调度算法或者请求处理逻辑,可能会影响到电梯状态管理相关代码。
缺乏模块化:整个程序缺乏清晰的模块划分,各个功能之间的耦合度较高。例如,Elevator 类内部的方法相互依赖,修改一个方法可能会对其他方法产生影响。
缺少抽象和接口:代码中没有使用抽象类或接口来定义电梯的行为,不利于代码的扩展和复用。若要添加新类型的电梯或者修改电梯的运行规则,就需要对现有代码进行大量修改。

第二次电梯对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类,具体设计可参考如下类图。
电梯运行规则与前阶段单类设计相同,但要处理如下情况:
乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
注意:本次作业类设计必须符合如上要求(包含但不限于乘客请求类、电梯类、请求队列类及控制类,其中控制类专门负责电梯调度过程),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次电梯程序提交到本次题目中测试)。

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。

电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<乘客所在楼层数,乘梯方向>,其中,乘梯方向用UP代表上行,用DOWN代表下行(UP、DOWN必须大写)。
当输入“end”时代表输入结束(end不区分大小写)。
类图:

总结与心得:本次迭代围绕单一职责原则展开,将电梯调度系统拆分为电梯类、乘客请求类、队列类以及控制类。电梯类专注于电梯的状态管理(当前楼层、运行方向、运行状态)与基础操作(移动、开门、关门);乘客请求类负责封装乘客请求信息,包括所在楼层与乘梯方向,并在构造函数中对楼层有效性进行初步判断;队列类通过集合数据结构管理乘客请求队列,不仅实现了请求的添加功能,还对重复请求进行过滤,保证队列中请求的唯一性;控制类则作为调度核心,依据电梯当前状态与请求队列情况,按照既定规则决定电梯的运行方向与停靠楼层,完成请求处理流程。
在处理输入请求时,程序首先解析输入字符串,根据格式判断是电梯内请求还是电梯外请求,进而创建相应的乘客请求对象。在添加请求到队列时,队列类会检查楼层有效性,若超出范围则自动忽略;同时,通过集合的特性(如HashSet的唯一性),对重复请求进行过滤,确保后续调度的准确性。

第三次电梯:对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客类、队列类以及控制类,具体设计可参考如下类图。

电梯运行规则与前阶段相同,但有如下变动情况:

乘客请求输入变动情况:外部请求由之前的<请求楼层数,请求方向>修改为<请求源楼层,请求目的楼层>
对于外部请求,当电梯处理该请求之后(该请求出队),要将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)
注意:本次作业类设计必须符合如上要求(包含但不限于设计电梯类、乘客类、队列类以及控制类),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次及第二次电梯程序提交到本次题目中测试)。

输入格式:
第一行输入最小电梯楼层数。
第二行输入最大电梯楼层数。
从第三行开始每行输入代表一个乘客请求。

电梯内乘客请求格式:<楼层数>
电梯外乘客请求格式:<请求源楼层,请求目的楼层>,其中,请求源楼层表示乘客发起请求所在的楼层,请求目的楼层表示乘客想要到达的楼层。
当输入“end”时代表输入结束(end不区分大小写)。


该题与上一题存在较多不同但大差不差,前一题:包含电梯类、乘客请求类、队列类以及控制类。乘客请求类负责表示乘客的请求,包括所在楼层和乘梯方向等信息,电梯类处理请求相关逻辑,如请求的添加判断、请求队列的管理等。
本题:包含电梯类、乘客类、队列类以及控制类。取消了乘客请求类,引入乘客类,乘客类不仅包含乘客的出发楼层信息,还包含目的楼层信息。并且将原本在电梯类中部分与请求相关的职责进一步拆分,使得各个类的职责更加明确和单一。
前一题:处理请求时,根据请求的楼层和方向添加到外部上行或下行请求队列,电梯根据当前运行方向优先处理同方向请求。
本题:对于外部请求,当电梯处理完该请求(出队)后,要将请求中的目的楼层加入到内部请求队列的队尾。这意味着电梯在处理外部请求后,还需要额外处理将目的楼层加入内部队列的操作,并且后续电梯的运行和停靠决策也会基于新的内部队列情况进行。
逻辑上的不同造成了需要考虑的东西较多以及逻辑的延申。
三。踩坑:面向对象概念理解不足:
类的职责划分不清:难以准确地将不同功能分配到相应的类中,比如把电梯的运行逻辑、请求处理逻辑和状态管理等都混杂在一个类里,导致类的职责过多,违反单一职责原则。像在第一次设计中,很多初学者会让 Elevator 类承担了请求队列管理、调度算法以及电梯状态管理等多项职责,使得代码复杂且难以维护。
对象间交互混乱:不明白如何合理地设计类与类之间的交互方式,导致对象之间的调用关系混乱。例如,乘客类、电梯类、队列类和控制类之间应该如何协作来完成请求处理和电梯运行,但初学者可能会出现控制类直接操作乘客类的内部属性,或者电梯类与队列类之间的交互逻辑错误等情况。
对题目需求理解有误:
运行规则理解偏差:对于电梯的运行规则,如优先处理同方向请求、在停止时如何根据新请求决定方向等,理解不够准确。可能会出现电梯在处理请求时,没有严格按照规则进行,比如在同方向还有请求时就切换方向去处理反方向请求。
请求处理细节遗漏:在处理乘客请求时,忽略题目中对无效请求(如楼层数超出范围)和重复请求的处理要求。或者对请求格式的理解不准确,在解析输入时出现错误,例如在第二次题目中,对于电梯外请求格式 <乘客所在楼层数,乘梯方向> 和电梯内请求格式 <楼层数> ,没有正确区分和处理。
新需求把握不准:当题目进行迭代,增加新的需求时(如第三次题目中外部请求格式的变化以及请求处理后目的楼层加入内部队列的要求),不能很好地理解和实现这些新变化,导致程序不符合题目要求。
四。改进建议:我认为自己在敲代码时需要考虑的东西变多了,首先是按照要求来编写程序,由于是首次接触类图,可能掌握程度较为浅显,但是我发现类图的作用是分大,类图明确了类的属性和方法,以及类之间的关系,为系统的详细设计和编码实现提供了清晰的指导。开发人员可以根据类图来确定每个类的具体职责、行为和数据结构,从而有条不紊地进行代码编写。同时,类图也有助于发现设计中的问题和缺陷,及时进行调整和优化。其次需要考虑代码的逻辑与现实是否符合,最后就是要勤加练习。
五。总结:对于我这种初学者来说,通过这几道关于电梯调度程序设计的题目能收获颇丰。首先,在面向对象编程的概念和原则方面,学会定义类,依据实际问题的不同概念和职责设计出电梯类、乘客类、队列类和控制类等,并理解单一职责原则,让每个类只负责一项主要功能,降低类间耦合度,提高代码可读性和可维护性,同时了解不同类对象间如何协同工作。其次,在程序设计与问题解决能力上,能学会分析题目需求,将实际问题转化为程序功能,设计有效的电梯调度算法,还能掌握错误和异常处理方法,使程序更健壮稳定。再者,在代码实现与调试技能方面,可熟练掌握编程语言基本语法,应用合适的数据结构,并且学会通过调试工具和日志输出等方法查找并解决代码错误。最后,在软件设计的可扩展性和维护性上,能学到模块化设计,将程序分模块,便于扩展和修改,以及实现代码复用,让设计良好的类和方法能在不同场景被多次使用。

posted @ 2025-04-20 23:07  郑煜韬  阅读(63)  评论(0)    收藏  举报