前言
这三次题目集让我学会了很多:
1.我学会正确使用import java.util.LinkedList和import java.util.List,比如其中的add函数以及remove函数;
2.学会一些字符串中的函数如contains(",")是判断是否有“,”,equalsIgnoreCase()是忽视大小写的比较,startsWith("<")endsWith(">")分别判断是否以<>开头与结尾substring(1, request.length() - 1)是截取字符串;
3.初步建立起了面向对象的设计思路;
4.学会了构建自动化测试工具,如PowerDesigner和SourceMonitor。
这三次题目集的难度对于我而言较大:
1.我对LinkedList和字符串中的函数并不熟悉;
2.在最开始的时候我对题目的分析有错误,只不过由于第一次测试时只有一个测试点才过关,直到第二次测试时才找到电梯的正确运行方式从而解题。
这三次题目集的题量中等,主要难点在于题目的分析,代码迭代的变化内容较少,我所写的代码长度较短。
设计与分析
题目集五
我认为题目的主要算法在于查找电梯运行后到达的下一层楼,在这道题目中主要考虑电梯的运行方向如果到内部楼层则直接开门,而如果运行到外部楼层,则需判断当前楼层的方向是否与电梯运行方向是否相同,如果相同,则开门,否则不开门,如果多次输入同一个数据只开一次门如1 20 <4,UP> <4,UP> <5> <5> <5> <6,DOWN> <7> <7> <3> <22,DOWN> <5,DOWN> <30> END输出为
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Open Door # Floor 4
Close Door
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
第五次测试的类图为:
复杂度分析
Percent Branch Statements:分支语句占比 29.4% ,近三成语句为分支结构。这表明程序运行时会依据不同条件执行多样路径,增强了程序灵活性与逻辑丰富度。但过多分支会使代码逻辑流程复杂,出现 “意大利面条式代码” 风险增加,测试时需覆盖更多场景,增加测试工作量与难度。
Method Call Statements:方法调用语句有 71 条,反映方法间调用频繁程度。
Percent Lines with Comments:含注释的代码行占比 9.6% ,注释较少,代码可读性可能受影响,说明我下次要多写注释。代码注释是沟通桥梁,能让开发者快速理解代码意图、算法逻辑、参数作用等。缺乏注释,对于新接手代码的人员,理解代码功能与逻辑需逐行分析,效率极低。长期来看,原开发者也可能遗忘代码细节,导致后期维护困难。从团队协作角度,不利于知识共享与代码传承。
Methods per Class:每个类平均方法数为 3.33 ,意味着类的功能相对丰富。
Average Statements per Method:每个方法平均语句数 9.70 ,方法规模适中。
Line Number of Most Complex Method:最复杂方法的行号是 176 ,对应方法 Main.main() 。
Maximum Complexity:最大复杂度为 3 ,表明代码逻辑复杂程度尚可。
Maximum Block Depth:最大代码块深度 5 ,反映代码嵌套层次。
Average Block Depth:平均代码块深度 1.77 。
Average Complexity:平均复杂度 1.75。
题目集六
这次题目集的主要要求是将题目集五的代码分为多个类,因此增加了代码的可读性。
第六次测试的类图为:
External 类:负责表示电梯外部乘客请求,封装了 floor(楼层)和 direction(方向)属性,提供构造方法及获取属性的方法,专注于外部请求数据的存储与访问 。
Elevator 类:管理电梯状态和行为,包含 minFloor(最低楼层)、maxFloor(最高楼层)、current(当前楼层)、direction(运行方向)等属性,有设置和获取属性的方法,还有判断楼层是否有效的静态方法,全面掌控电梯相关信息与操作 。
RequestQueue 类:管理电梯内外部请求,持有内部请求列表 intern(List
Controller 类:协调 Elevator 和 RequestQueue 类,控制电梯运行及请求处理。通过构造函数接收电梯和请求队列实例,包含处理请求、移动电梯、确定运行方向等方法,在整体逻辑中起调度作用 。
复杂度分析
逻辑复杂性影响:分支语句占比达 27.3% ,近三分之一。这意味着程序在执行过程中存在多种条件判断,根据不同条件走不同执行路径。if - else 语句会大量出现。这种情况一方面体现了程序能够灵活应对不同的输入和场景,实现多样化的功能;但另一方面,过多的分支会使代码的逻辑流程变得错综复杂,就像一张交织的网,代码的可读性和可维护性会受到影响。从测试角度来看,分支语句多意味着需要更多的测试用例来覆盖各种可能的执行路径。每一个分支条件都可能产生不同的结果,若测试不全面,就容易遗漏一些潜在的问题,导致程序在实际运行中出现错误。
123 条方法调用语句,体现出代码较高的模块化程度。通过将不同的功能封装成一个个独立的方法,实现了代码的复用。然而,大量的方法调用也会带来一些问题。方法之间的调用关系可能会形成一个复杂的网络,当出现问题时,很难快速定位到具体是哪个方法调用环节出现了错误。而且,方法调用过程中涉及到参数传递、返回值处理等操作,过多的调用会增加这些操作的复杂性。
注释占比为 19.3% ,相较于之前有所提升,这对代码的可读性有一定的增强作用,但还是不够多。
最大复杂度为 5 ,说明代码中存在一些逻辑较为复杂的区域。
平均复杂度综合评估:平均复杂度为 1.42 ,从整体上说明代码的逻辑复杂程度尚可。虽然存在局部的复杂区域,但大部分代码的逻辑相对简单。
题目集七
这次题目集改变在于外部储存类型改变为<5,4>,同时加入乘客类(Passenger),取消乘客请求类,我认为只需将<5,4>判断方向并在外部楼层开门后将<请求源楼层,请求目的楼层>中的请求目的楼层加入到请求内部队列(加到队尾)即可。
第七次测试的类图为:
Passenger 类:用于表示乘客信息,包含 sourcefloor(起始楼层)、destinationfloor(目标楼层)和 direction(方向)属性,提供构造函数和获取属性的方法,专注于乘客请求数据的封装。
Elevator 类:管理电梯的状态和行为,有 minFloor(最低楼层)、maxFloor(最高楼层)、current(当前楼层)、direction(运行方向)等属性,以及设置和获取这些属性的方法,还有判断楼层是否有效的静态方法,全面负责电梯相关信息的管理和操作。
RequestQueue 类:负责管理电梯的内部请求和外部请求,持有内部请求列表 intern(List
Controller 类:协调 Elevator 和 RequestQueue 类,通过构造函数接收电梯和请求队列实例,包含处理请求、移动电梯、确定运行方向等方法,在电梯运行控制和请求处理中起调度作用。
复杂度分析
分支语句占比达 27.3% ,近三分之一。在程序执行时,这使得代码逻辑存在多种走向。比如在一个电梯调度程序中,根据不同楼层的请求、电梯当前状态等条件,通过 if - else 或 switch 等分支语句来决定电梯的运行方向、是否停靠等操作。这种多路径的逻辑增加了程序的灵活性,能应对复杂的业务场景。但从另一方面看,每一个分支就像一条岔路,过多的分支会使代码逻辑流程图变得错综复杂,犹如迷宫一般。这不仅增加了开发过程中的调试难度,也使得代码后期的维护成本大幅上升,任何一个分支的改动都可能影响其他路径的正常运行。
最复杂方法 Main.main (),逻辑复杂。作为程序入口,它可能承担了过多的初始化、调度等工作。大量的功能集中在该方法内,导致其代码行数较多,可读性变差。一旦程序出现问题,定位和修复错误的难度也随之增加,需要对整个程序的运行流程有全面的理解才能有效排查问题。
最深代码块行号为 127,最大代码块深度为 5,平均代码块深度为 1.63。平均代码块深度较低说明多数代码块结构简单,但最大代码块深度较深,反映出存在嵌套层次较深的代码块。过深的代码块嵌套不仅会让代码的逻辑结构变得晦涩难懂,还容易引发潜在的性能问题,例如过多的方法调用栈深度可能导致栈溢出错误,同时也会给代码的测试和维护带来巨大挑战。
采坑心得
这一系列题目一开始我出现了许多的错误
1.分析错误,一开始我查找下一楼层是依靠外部楼层方向判断
导致运行时会出现逻辑错误如1 10 <4,DOWN> <5> end
输出为:
Current Floor: 1 Direction: UP
Current Floor: 2 Direction: UP
Current Floor: 3 Direction: UP
Current Floor: 4 Direction: UP
Open Door # Floor 4
Close Door
Current Floor: 5 Direction: UP
Open Door # Floor 5
Close Door
后来我改为通过当前方向判断下一层楼
2.重复开门,如<5><5>会重复开门,我在RequestQueue类中加入lastRequest如果本次加入数据与lastRequest一样,则不添加
改进建议
我认为题目集七中开门后将 <请求源楼层,请求目的楼层> 中的请求目的楼层加入到请求内部队列 (加到队尾)即可,这种处理方式虽能实现基础功能,但从实际应用场景和代码健壮性角度来看,存在优化空间。请求目的楼层不应该直接加入内部队列 (加到队尾),而是单独放入一个新的队列,同时进行下一楼层判断才更符合日常逻辑。如此一来,不仅能更清晰地区分不同类型的请求,避免逻辑混淆,还可以在后续需求变更或扩展时,更方便地对特定请求队列进行操作和管理,提升代码的扩展性与维护性。
总结
在这一系列题目集中,我收获颇丰。技术层面,我熟练掌握了 import java.util.LinkedList 和 import java.util.List ,能自如运用其中的 add 函数和 remove 函数来管理数据集合,极大提升了数据处理能力。对于字符串操作函数,像 contains(",") 用于判断字符存在、equalsIgnoreCase() 实现大小写无关比较、startsWith("<") 与 endsWith(">") 进行首尾判断以及 substring(1, request.length() - 1) 完成字符串截取等,都有了深刻理解与实践应用。
思维层面,我深刻认识到全面分析的重要性。做题目集五时,虽侥幸通过,但因分析错误,在题目集六时遭遇诸多困境,代码大改。这让我明白,前期全面且深入的分析,是构建稳健代码架构的基石,能有效避免后期返工,提升开发效率与代码质量。未来,我将把这些经验融入学习与实践,不断提升编程水平。
此外,通过对类与类之间关系的梳理以及代码复杂度的分析,我对面向对象编程有了更透彻的领悟。明白了合理的类设计和职责划分,能让代码结构更清晰、可维护性更强。同时,这些经历也锻炼了我的调试和纠错能力,在未来面对复杂编程任务时,我能更从容地应对挑战,以更严谨的态度追求代码的完美。