第一次blog作业

前言
学习java和写电梯的整体感受
java的学习并不容易,C语言是一门面向过程的语言,而java是面向对象的,我起初一直理解不了java这种面向对象是什么意思,一直保留着面向过程的思维,再加上我C语言的基本不好,这次大作业对我来说是一个艰难痛苦的过程,虽然这次的电梯我基本都没写出来,但在后续询问他人以及自己不断摸索过程中我渐渐也明白和学会了一些,这是一个不断进步的过程。

踩坑感受
第一次大作业
第一次看到电梯题目我就有点被劝退了,试着慢慢写了一些,结果出现了一堆错误
对正则表达式的学习不够熟练,在 Main 类中,外部请求和内部请求的正则表达式判断有误。外部请求的正则表达式 "<\d+,UP|DOWN>" 无法正确处理输入字符串中的空格等情况,内部请求的正则表达式 "\d+" 没有考虑输入字符串应包含 <> 符号的情况,导致格式判断错误。在电梯程序中,我没有清晰地界定当内部请求队列和外部请求队列都为空时,电梯就不需要再继续运行了。,导致在processRequests方法和Main类的main方法中。都存在 while(true)这样的无限循环,没有合适的退出条件,会导致程序一直运行,无法正常结束。然后我就改正,在 processRequests 方法中,将 while (true)替换为 while(!internalRequests.isEmpty() || !externalRequests.isEmpty()),确保只有在内部请求队列或外部请求队列不为空时才继续循环在 Main类中,去掉多余的while(true)循环,因为processRequests方法已经处理了所有请求不需要额外的循环调用。
第二次大作业
第二次总结了之前的经验,之前的细节毛病有所改善
但我在处理请求队列非空判断时,仅简单地获取队列头部元素判断方向,队列中后续有更合适的请求,导致电梯方向判断错误。例如,当前电梯在底层,内部请求队列头部是较高楼层,但后续有更低楼层请求,按此逻辑电梯会向上运行,而可能更合理的是先处理更低楼层请求向下运行。此外,没有考虑到电梯初始状态下,方向和状态设置的边界情况。第二天在请教了同学之后,在帮助下,我进行了合理的修改
这里我对 determineDirection 方法的修改,综合考虑内部请求和外部请求,选择离当前楼层最近的请求来确定电梯运行方向。
第三次大作业
第三次依旧没写出来,但结合之前经验,问题也明显减少,但在开始写时遇到了
在后续询问同学后,发现代码中使用了elevator.isValidFloor(floor),但elevator变量未在RequestQueue类中定义,后面重新在RequestQueue类中添加了Elevator类型的成员变量elevator

设计与分析
第一次电梯
题目:
设计一个电梯类,具体包含电梯的最大楼层数、最小楼层数(默认为1层)当前楼层、运行方向、运行状态,以及电梯内部乘客的请求队列和电梯外部楼层乘客的请求队列,其中,电梯外部请求队列需要区分上行和下行。
电梯运行规则如下:电梯默认停留在1层,状态为静止,当有乘客对电梯发起请求时(各楼层电梯外部乘客按下上行或者下行按钮或者电梯内部乘客按下想要到达的楼层数字按钮),电梯开始移动,当电梯向某个方向移动时,优先处理同方向的请求,当同方向的请求均被处理完毕然后再处理相反方向的请求。电梯运行过程中的状态包括停止、移动中、开门、关门等状态。当电梯停止时,如果有新的请求,就根据请求的方向或位置决定移动方向。电梯在运行到某一楼层时,检查当前是否有请求(访问电梯内请求队列和电梯外请求队列),然后据此决定移动方向。每次移动一个楼层,检查是否有需要停靠的请求,如果有,则开门,处理该楼层的请求,然后关门继续移动。
使用键盘模拟输入乘客的请求,此时要注意处理无效请求情况,例如无效楼层请求,比如超过大楼的最高或最低楼层。还需要考虑电梯的空闲状态,当没有请求时,电梯停留在当前楼层。
请编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法,并使用一些测试用例,模拟不同的请求顺序,观察电梯的行为是否符合预期,比如是否优先处理同方向的请求,是否在移动过程中处理顺路的请求等。为了降低编程难度,不考虑同时有多个乘客请求同时发生的情况,即采用串行处理乘客的请求方式(电梯只按照规则响应请求队列中当前的乘客请求,响应结束后再响应下一个请求),具体运行规则详见输入输出样例。

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

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

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例:
在这里给出一组输入。例如:

1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
end
输出样例:
在这里给出相应的输出。例如:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
Metrics Details For File 'Main.java'

Parameter Value
========= =====
Project Directory D:\code\di\dianti\src
Project Name
Checkpoint Name Baseline
File Name Main.java
Lines 224
Statements 123
Percent Branch Statements 22.8
Method Call Statements 66
Percent Lines with Comments 12.1
Classes and Interfaces 1
Methods per Class 12.00
Average Statements per Method 9.67
Line Number of Most Complex Method 172
Name of Most Complex Method Main.main()
Maximum Complexity 9
Line Number of Deepest Block 189
Maximum Block Depth 5
Average Block Depth 1.45
Average Complexity 9.00


Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls

Main.main() 9, 26, 5, 24


Block Depth Statements

0 33
1 36
2 32
3 12
4 8
5 2
6 0
7 0
8 0
9+ 0

第二次电梯
对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP),要求必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类,具体设计可参考如下类图。
电梯迭代1类图.png
电梯运行规则与前阶段单类设计相同,但要处理如下情况:

乘客请求楼层数有误,具体为高于最高楼层数或低于最低楼层数,处理方法:程序自动忽略此类输入,继续执行
乘客请求不合理,具体为输入时出现连续的相同请求,例如<3><3><3>或者<5,DOWN><5,DOWN>,处理方法:程序自动忽略相同的多余输入,继续执行,例如<3><3><3>过滤为<3>
注意:本次作业类设计必须符合如上要求(包含但不限于乘客请求类、电梯类、请求队列类及控制类,其中控制类专门负责电梯调度过程),凡是不符合类设计要求此题不得分,另外,PTA得分代码界定为第一次提交的最高分代码(因此千万不要把第一次电梯程序提交到本次题目中测试)。

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

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

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例1:
在这里给出一组输入。例如:

1
20
❤️,UP>
<5>
<6,DOWN>
<7>
<3>
end
输出样例1:
在这里给出相应的输出。例如:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
输入样例2:
在这里给出一组输入。例如:

1
20
❤️,UP>
❤️,UP>
<5>
<5>
<5>
<6,DOWN>
<7>
<7>
<3>
<22,DOWN>
<5,DOWN>
<30>
END
输出样例2:
在这里给出相应的输出。例如:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Open Door # Floor 3
Close Door
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Open Door # Floor 6
Close Door
Current Floor: 5 Direction: DOWN
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door
Metrics Details For File 'Main.java'

Parameter Value
========= =====
Project Directory D:\code\di\dianti2\src
Project Name
Checkpoint Name Baseline
File Name Main.java
Lines 294
Statements 169
Percent Branch Statements 16.6
Method Call Statements 121
Percent Lines with Comments 2.0
Classes and Interfaces 2
Methods per Class 17.00
Average Statements per Method 4.76
Line Number of Most Complex Method 239
Name of Most Complex Method Main.main()
Maximum Complexity 6
Line Number of Deepest Block 276
Maximum Block Depth 5
Average Block Depth 1.24
Average Complexity 6.00


Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls

Main.main() 6, 20, 5, 16


Block Depth Statements

0 49
1 61
2 39
3 12
4 6
5 2
6 0
7 0
8 0
9+ 0


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

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

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

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

运行到某一楼层(不需要停留开门),输出一行文本:
Current Floor: 楼层数 Direction: 方向
运行到某一楼层(需要停留开门)输出两行文本:
Open Door # Floor 楼层数
Close Door
输入样例1:
在这里给出一组输入。例如:

1
20
<5,4>
<5>
<7>
end
输出样例1:
在这里给出相应的输出。例如:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Open Door # Floor 7
Close Door
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Open Door # Floor 5
Close Door
Current Floor: 4 Direction: DOWN
Open Door # Floor 4
Close Door
输入样例2:
在这里给出一组输入。例如:

1
20
<5,9>
<8>
<9,3>
<4>
<2>
end
输出样例2:
在这里给出相应的输出。例如:

Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Open Door # Floor 8
Close Door
Current Floor: 9 Direction: UP
Open Door # Floor 9
Close Door
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Open Door # Floor 4
Close Door
Current Floor: 3 Direction: DOWN
Current Floor: 2 Direction: DOWN
Open Door # Floor 2
Close Door
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Current Floor: 5 Direction: UP
Current Floor: 6 Direction: UP
Current Floor: 7 Direction: UP
Current Floor: 8 Direction: UP
Current Floor: 9 Direction: UP
Open Door # Floor 9
Close Door
Current Floor: 8 Direction: DOWN
Current Floor: 7 Direction: DOWN
Current Floor: 6 Direction: DOWN
Current Floor: 5 Direction: DOWN
Current Floor: 4 Direction: DOWN
Current Floor: 3 Direction: DOWN
Open Door # Floor 3
Close Door

Metrics Details For File 'Main.java'

Parameter Value
========= =====
Project Directory D:\code\di\dianti3\src
Project Name
Checkpoint Name Baseline
File Name Main.java
Lines 298
Statements 170
Percent Branch Statements 16.5
Method Call Statements 113
Percent Lines with Comments 2.0
Classes and Interfaces 2
Methods per Class 17.50
Average Statements per Method 4.66
Line Number of Most Complex Method 235
Name of Most Complex Method Main.main()
Maximum Complexity 4
Line Number of Deepest Block 280
Maximum Block Depth 4
Average Block Depth 1.16
Average Complexity 4.00


Most Complex Methods in 1 Class(es): Complexity, Statements, Max Depth, Calls

Main.main() 4, 18, 4, 14


Block Depth Statements

0 50
1 65
2 39
3 10
4 6
5 0
6 0
7 0
8 0
9+ 0

改进建议
第一次电梯迭代题代码改进建议
代码结构与职责划分:整体代码结构较为单一,没有严格遵循单一职责原则。例如,Elevator 类承担了过多职责,既处理电梯自身状态,又负责请求处理等逻辑。建议进一步拆分功能,将请求处理相关逻辑移至专门的控制类,如 Controller 类,使每个类专注于自己的核心功能,提高代码的可维护性和可读性。
请求处理逻辑:在处理乘客请求时,对于不合理请求(如楼层数有误、连续相同请求)的过滤逻辑不够完善。可以在接收请求的环节,增加更严格的校验。比如,在 Main 类中,读取输入后先进行全面的格式和有效性检查,对于无效请求直接提示用户并跳过,而不是等到后续处理时才忽略。
代码复杂度:从图片信息看,代码复杂度较高。可以通过提取重复代码到方法中,减少方法内的语句数量和分支数量。例如,将判断电梯是否应停止、改变方向等逻辑提取为独立的方法,降低 processRequests 等方法的复杂度。
注释与文档:代码中缺少注释,对于复杂的逻辑和方法功能没有说明。添加注释可以帮助自己和他人更好地理解代码意图,尤其是在判断电梯运行方向、处理请求等关键逻辑处,应详细注释说明。

第二次电梯迭代题代码改进建议
类设计与协作:虽然已经按照类图设计了多个类,但部分类之间的协作还可以优化。例如,RequestQueue 类在添加请求时,对楼层有效性的判断依赖于未定义的 elevator 变量,这是设计上的缺陷。应确保类之间的依赖关系清晰、合理,在构造函数中正确传递所需的对象引用,保证功能的正常实现。
请求队列管理:对于请求队列中重复请求的过滤逻辑,仅考虑了与队列末尾元素的比较,存在局限性。可以采用更有效的数据结构或算法,如使用 HashSet 辅助判断内部请求是否重复,对于外部请求可以结合楼层和方向构建唯一标识进行判断,避免非连续的重复请求进入队列。
边界情况处理:在电梯移动和方向判断等逻辑中,对边界情况的处理不够全面。比如,在电梯到达最高或最低楼层时,没有明确的逻辑处理,可能导致程序出现异常。应增加对这些边界情况的判断和处理,确保电梯在任何情况下都能正常运行。
代码可读性:部分方法的命名和代码布局可以优化,提高代码的可读性。例如,一些方法名可以更加直观地反映其功能,代码块之间可以适当增加空行,使代码结构更清晰。

第三次电梯迭代题代码改进建议
输入处理优化:在 Main 类的输入处理部分,虽然对请求格式进行了一定的校验,但可以进一步增强。例如,对于输入的楼层和方向,除了格式检查外,还可以增加范围检查(如方向只能是 UP 或 DOWN 等),提高程序的健壮性。
控制类逻辑:Controller 类中部分逻辑可以进一步简化和优化。比如,在 determineDirection 方法中,确定电梯运行方向的逻辑可以考虑更多因素,如电梯当前负载、不同楼层请求的优先级等,使电梯调度更加智能合理。
代码复用与模块化:可以进一步提高代码的复用性,将一些通用的功能提取为独立的模块或工具类。例如,将请求格式校验、楼层有效性判断等功能提取出来,方便在不同的类中复用,减少代码冗余。
错误处理与日志:目前代码中对于可能出现的错误(如输入异常、请求处理异常等)处理不够完善。可以添加适当的错误处理机制,如捕获异常并进行日志记录,方便排查问题,同时在出现错误时给予用户友好的提示。
总结
作为一名未来要成为程序员的学生,在完成这三次电梯迭代题的过程中,我收获颇丰,也深刻认识到自己在代码编写上存在的不足。
从代码结构角度来看,最初我对单一职责原则理解不够深刻,导致代码结构混乱,类的职责不清晰。经过几次迭代,虽然在类的设计上有了明显进步,但仍存在一些依赖关系不合理的问题。这让我明白,良好的代码结构是构建可维护、可扩展程序的基础,在后续开发中,我需要更加注重类的职责划分,确保每个类都专注于自己的核心任务,提高代码的模块化程度。
在逻辑处理方面,从最初对不合理请求处理不完善,到逐渐增加各种过滤和校验逻辑,我体会到了严谨性的重要性。同时,在电梯运行方向判断、边界情况处理等关键逻辑上,我不断进行优化,但仍有提升空间。这提醒我在编写代码时,要全面考虑各种可能的情况,对边界条件和异常情况进行充分的测试和处理,使程序更加健壮可靠。
关于代码复杂度和可读性,我意识到代码的简洁和清晰是提高开发效率和代码质量的关键。复杂的代码不仅难以理解和维护,还容易隐藏错误。通过提取重复代码、优化方法命名和布局等方式,可以有效降低代码复杂度,提高可读性。在今后的编程中,我会更加注重代码的简洁性和规范性,遵循代码编写的最佳实践。
在错误处理和日志方面,我认识到完善的错误处理机制对于程序的稳定性和可维护性至关重要。及时捕获异常并进行合理处理,同时记录详细的日志信息,能够帮助我快速定位和解决问题。这是我在后续开发中需要重点加强的部分。
通过这三次电梯迭代题,我在编程能力上有了一定的提升,但也清楚地知道自己还有很多需要学习和改进的地方。在未来的学习和实践中,我将不断总结经验教训,持续优化自己的代码,努力提高编程水平。

posted @ 2025-04-20 14:27  xuan324  阅读(28)  评论(0)    收藏  举报