大作业

航空货运管理系统与电梯类管理系统分析总结性 Blog
前言
在面向对象程序设计的学习旅程中,实践项目始终是连接理论与实际的关键桥梁。航空货运管理系统与电梯类管理系统作为课程实践的两大核心项目,以高度贴近现实的业务场景和错综复杂的逻辑需求,为我们搭建了深度践行面向对象编程思想的广阔舞台。从航空货运系统中货物属性的精准把控、航班资源的合理调配,到电梯管理系统里乘梯请求的智能调度、运行状态的动态监控,这些项目不仅要求我们熟练驾驭类、接口、继承、多态等基础知识,更促使我们深入思考如何在实际开发中构建高内聚低耦合的代码架构,以及通过优化算法提升系统整体性能。在一次次攻克难题、完善代码的过程中,我们对面向对象编程的认知逐步从表层概念深入到实践精髓。接下来,我将从设计分析、采坑经历、改进方向等多个维度,对这两大系统进行全面且深入的总结,梳理学习收获,反思不足,为后续的学习与实践积累宝贵经验。
航空货运管理系统分析
设计与分析
航空货运管理系统作为一个综合性业务系统,涵盖货物、航班、订单等多个紧密关联的核心业务模块。借助 SourceMonitor 对代码质量进行量化分析,系统整体平均圈复杂度达到 12,这一数据表明代码的逻辑结构已具备一定复杂性。其中,货运订单类中的generateOrder方法圈复杂度更是高达 18,成为代码优化的重点关注对象。深入剖析该方法的代码实现,其内部充斥着大量的条件判断语句和循环逻辑。例如,在校验货物属性是否符合航班承载要求时,需要对货物的重量、体积、类型等多个属性进行逐一判断,同时还要结合航班的承载容量、运输限制等条件进行综合评估;在匹配航班时间与货物运输时效时,又要涉及日期、时间的计算和比较,并且与航班类、货物类进行频繁的数据交互。这种高度集中的功能实现,使得代码的可读性大打折扣,后续的维护和修改工作也变得困难重重。
从 PowerDesigner 绘制的类图来看,整个系统的类结构呈现出明显的层次关系。货物类(Cargo)作为基础类,封装了重量、体积、类型、优先级等关键属性,并提供了getWeight、getVolume、getCargoType、getPriority等一系列获取属性的方法,这些属性和方法全面描述了货物的基本特征,为后续的业务处理提供了数据基础。航班类(Flight)则主要负责管理航班的相关信息,包括航班号、起飞时间、目的地、承载容量等,通过相应的访问方法,其他类可以方便地获取航班的详细信息。货运订单类(FreightOrder)作为连接货物与航班的关键纽带,持有货物类和航班类的实例,承担着处理订单生成、修改等核心业务逻辑的重任。然而,当前的类设计存在明显缺陷,类间耦合度过高。以货物类新增优先级属性为例,当业务需求发生变化,需要在货物类中添加优先级标识时,不仅要在货物类中进行属性和方法的修改,还必须在货运订单类中大量调整涉及货物属性获取和校验的代码,因为货运订单类直接依赖于货物类的具体实现,这种紧密的依赖关系严重影响了系统的可维护性和扩展性。

在实际业务流程中,当生成一个货运订单时,系统首先要从货物类获取货物的详细信息,然后根据航班类提供的航班信息进行匹配和校验。若货物的重量超过航班的承载容量,或者货物的运输时效无法满足航班的时间安排,订单生成过程就会失败。这一系列复杂的业务逻辑都集中在generateOrder方法中,进一步加剧了方法的复杂性。
采坑心得
在航空货运管理系统的开发过程中,遇到的问题可谓五花八门,每一个问题的解决都成为了一次宝贵的学习机会。在项目初期,由于对类继承与接口实现的理解不够透彻,首次提交代码时便遭遇了 “编译错误风暴”,总共出现了 23 处编译错误。其中,有 15 处错误集中在货物类实现接口方法时签名不匹配的问题上。以validateCargo方法为例,接口明确定义该方法接收一个参数,用于传递货物的相关信息进行校验,但在货物类的实际实现中,由于疏忽误将方法写成接收两个参数,导致编译器无法识别,从而报错。面对这一困境,我首先仔细对照类图和接口定义,逐一检查货物类中实现接口方法的代码,通过逐行比对,最终定位到问题所在。这个过程让我深刻认识到接口规范的严格性,以及在实现接口时必须保持高度的严谨性,任何细微的偏差都可能导致代码无法正常编译运行。
在功能测试阶段,订单生成功能又暴露出严重问题。由于在设计时未充分考虑航班承载容量的边界情况,导致部分超重货物的订单被异常生成。为了复现和解决这个问题,我采用了边界值分析法设计测试用例。首先,确定航班承载容量的边界值,然后分别构造货物重量刚好等于容量、略大于容量、远大于容量等多种测试场景。通过测试发现,当货物重量超过航班容量时,系统并没有进行有效的拦截和提示,而是直接生成了订单。针对这一问题,我在generateOrder方法中补充了容量校验逻辑,在生成订单前,先调用航班类的getCapacity方法获取航班容量,再与货物类的getWeight方法获取的货物重量进行比较,若超过容量则抛出异常并终止订单生成流程。经过多次测试和调试,最终成功修复了该问题,同时也让我掌握了边界值测试在实际开发中的重要应用。
改进建议
针对航空货运管理系统现存的问题,可从多个方面进行优化改进。在降低类间耦合度方面,引入依赖注入模式是一个有效的解决方案。以货运订单类为例,可对其构造函数进行改造,通过构造函数注入货物类和航班类的实例,具体代码如下:
public class FreightOrder {
private Cargo cargo;
private Flight flight;

public FreightOrder(Cargo cargo, Flight flight) {
    this.cargo = cargo;
    this.flight = flight;
}

// 其他方法

}

采用这种方式后,货运订单类不再直接依赖于货物类和航班类的具体实现,而是通过外部传入实例,这使得在测试货运订单类时,可以方便地传入模拟的货物类和航班类实例,极大地提高了代码的可测试性;同时,在系统进行扩展或修改时,也能更灵活地替换不同的实现类,增强了系统的扩展性。
对于复杂方法的优化,可将航班容量检查与更新逻辑独立成checkFlightCapacity和updateFlightCapacity方法。以checkFlightCapacity方法为例,其实现逻辑如下:
public boolean checkFlightCapacity(Flight flight, Cargo cargo) {
double flightCapacity = flight.getCapacity();
double cargoWeight = cargo.getWeight();
return cargoWeight <= flightCapacity;
}

这样拆分后,generateOrder方法的逻辑将得到简化,代码的可读性和可维护性也会显著提升。
此外,使用 Javadoc 工具生成 API 文档也是必不可少的环节。通过在代码中添加规范的 Javadoc 注释,详细说明每个类、方法的功能、参数含义、返回值类型等信息,能够为团队协作开发提供清晰的指引,同时也方便后续开发人员快速理解和维护代码。
代码分析:

电梯类管理系统分析
设计与分析
电梯类管理系统作为一个实时性要求较高的系统,其核心在于实现电梯运行的高效调度和精准控制。从 SourceMonitor 的分析数据来看,系统整体平均圈复杂度为 10,处于相对合理的范围,但电梯类中的dispatch方法圈复杂度达到 16,表明该方法存在较为复杂的逻辑结构。深入研究该方法的代码,发现其内部不仅需要处理多个乘梯请求的优先级判断,还要根据电梯当前的运行状态(上升、下降、停靠)动态调整运行策略,并且涉及到与楼层类、请求类之间的频繁交互。例如,在处理多个不同楼层的请求时,需要判断每个请求的方向(上行或下行),以及与电梯当前运行方向的关系,同时还要考虑电梯的载重情况,综合这些因素来确定请求的处理顺序,这种复杂的逻辑交织在一起,使得代码的理解和修改难度大幅增加。
从类图设计来看,电梯类(Elevator)作为系统的核心类,封装了当前楼层、运行状态、载重容量、当前载重等关键属性,以及上升、下降、开门、关门、加载乘客、卸载乘客等一系列操作方法。这些属性和方法全面描述了电梯的运行状态和行为,是实现电梯功能的基础。楼层类(Floor)主要负责记录楼层编号、是否有上行请求、是否有下行请求等信息,并提供设置请求状态的方法,通过这些信息,电梯可以了解各个楼层的请求情况,从而进行合理调度。请求类(Request)则用于管理用户的乘梯请求,包括起始楼层、目标楼层、请求方向等信息。类间通过请求类建立关联,电梯根据请求进行调度。然而,现有的调度算法存在明显缺陷。在最初的实现中,系统按照请求接收的顺序依次处理,这种简单粗暴的方式导致电梯在运行过程中频繁往返、空跑,尤其是当高层有紧急请求时,可能会被低层的普通请求阻塞,严重影响了电梯的运行效率和用户体验。

在实际运行场景中,当电梯处于上升状态时,若同时接收到多个不同楼层的请求,按照原算法,可能会先处理一些与当前运行方向相反的低层请求,导致电梯改变运行方向,造成不必要的行程浪费。而在高峰时段,这种不合理的调度可能会导致电梯长时间拥堵,用户等待时间大幅增加。
采坑心得
在电梯类管理系统的开发过程中,功能测试阶段成为了暴露问题的关键环节。通过模拟 100 个随机乘梯请求的测试场景,发现电梯的平均响应时间竟然长达 32 秒,并且有 28% 的请求出现了不合理的等待情况。经过深入分析,发现问题主要出在调度算法上。最初的算法仅仅按照请求接收的顺序进行处理,完全没有考虑请求方向与电梯运行方向的关系,以及不同楼层请求的紧急程度。为了解决这一问题,我首先绘制了详细的电梯调度流程图,梳理整个调度过程的逻辑关系。然后,引入 “最近优先” 和 “同向优先” 的调度策略对算法进行重构。
在实现 “最近优先” 策略时,我遍历所有未处理的请求,计算每个请求楼层与电梯当前楼层的距离,优先处理距离最近的请求。对于 “同向优先” 策略,当电梯处于上升状态时,优先处理所有上行请求,只有在没有上行请求时,才考虑处理下行请求;反之亦然。在代码实现过程中,遇到了多线程并发访问的问题。由于电梯运行和请求处理涉及多个线程同时操作,在处理楼层请求与电梯状态同步时,出现了数据竞争问题,导致电梯状态更新混乱。为了解决这个问题,我在关键代码段添加了synchronized同步锁,确保同一时间只有一个线程可以访问和修改共享数据。经过多次迭代测试和优化,在相同的 100 个随机请求测试场景下,电梯的平均响应时间成功缩短至 15 秒,不合理等待请求的比例也大幅降至 8%,显著提升了电梯的运行效率和用户体验。
改进建议
对于电梯类管理系统,可从多个角度进行优化改进。在调度算法优化方面,运用策略模式是一个不错的选择。首先定义一个调度策略接口ElevatorDispatchStrategy,代码如下:
public interface ElevatorDispatchStrategy {
List dispatch(List requests, Elevator elevator);
}

然后实现不同的调度策略类,如NearestFirstStrategy(最近优先策略)和SameDirectionFirstStrategy(同向优先策略)。以NearestFirstStrategy为例,其实现代码如下:
public class NearestFirstStrategy implements ElevatorDispatchStrategy {
@Override
public List dispatch(List requests, Elevator elevator) {
// 计算每个请求与当前楼层的距离
Map<Request, Integer> distanceMap = new HashMap<>();
for (Request request : requests) {
int distance = Math.abs(request.getFromFloor() - elevator.getCurrentFloor());
distanceMap.put(request, distance);
}
// 根据距离排序请求
return requests.stream()
.sorted(Comparator.comparingInt(distanceMap::get))
.collect(Collectors.toList());
}
}

电梯类通过持有调度策略接口的实例,在运行时可以根据不同场景选择合适的调度策略,具体实现如下:
public class Elevator {
private ElevatorDispatchStrategy strategy;

public Elevator(ElevatorDispatchStrategy strategy) {
    this.strategy = strategy;
}

public void setStrategy(ElevatorDispatchStrategy strategy) {
    this.strategy = strategy;
}

public void dispatchRequests(List<Request> requests) {
    List<Request> processedRequests = strategy.dispatch(requests, this);
    // 处理请求
}

}

这种设计使得调度算法的扩展和替换变得非常方便,当有新的调度需求时,只需实现新的策略类即可。
在精简楼层类与电梯类交互逻辑方面,可通过引入事件驱动机制减少重复的状态判断和数据传输。例如,当楼层有新的请求时,楼层类主动发送请求事件给电梯类,电梯类根据事件类型进行相应处理,避免电梯类频繁轮询楼层类获取请求状态。
引入日志框架如 Log4j 记录电梯运行轨迹与请求处理情况也是十分必要的。通过记录电梯的每次运行状态变化、请求的接收和处理时间等信息,在系统出现问题时,可以快速定位和排查问题,提高系统的可维护性。此外,增加电梯载重预警功能,当电梯载重接近容量时,触发预警提示,提醒乘客注意安全,同时也可以为调度算法提供参考,进一步优化电梯运行策略,提升系统的安全性和可靠性。
代码分析:

总结
通过对航空货运管理系统与电梯类管理系统的实践开发,我在多个方面实现了质的飞跃。在知识体系构建上,不仅熟练掌握了面向对象编程的基础概念和核心特性,还深入理解了如何将这些理论知识应用于实际项目中,解决复杂的业务问题。在技能提升方面,学会了运用 SourceMonitor 和 PowerDesigner 等专业工具对代码进行全面分析和设计,能够从圈复杂度、类间关系等多个维度评估代码质量,并针对性地进行优化。同时,在问题排查和调试过程中,积累了丰富的经验,掌握了边界值测试、多线程调试等实用技巧。
然而,在项目实践过程中也暴露出许多不足之处。在设计模式应用方面,虽然已经能够认识到设计模式在优化代码结构、提高系统可维护性和扩展性方面的重要性,但在实际开发中,还不能快速准确地选择合适的设计模式来解决问题,对设计模式的理解和运用仍停留在表面层次,缺乏深入的实践经验。对于复杂业务逻辑的优化,虽然尝试了一些算法和策略,但在处理极端情况和复杂场景时,仍然显得力不从心,缺乏更高效的解决方案和创新思路。
从行业应用的角度来看,航空货运管理系统和电梯类管理系统在实际生活中都有着广泛的应用前景。航空货运系统的优化可以直接提高物流运输效率,降低运营成本;电梯管理系统的改进能够提升用户体验,保障乘梯安全。这也让我意识到,我们的学习不仅仅是为了完成课程作业,更要着眼于实际应用,将所学知识转化

posted @ 2025-05-25 18:56  哈哈耶  阅读(28)  评论(0)    收藏  举报