Java 大作业总结
在 Java 学习的征程中,两次大作业犹如重要的里程碑,不仅检验了我对知识的掌握程度,更让我在实践中实现了能力的跃升。每一次大作业都是一次挑战,也是一次成长的契机,下面将对两次大作业进行详细的总结与分析。
一、前言
两次 Java 大作业紧密围绕实际应用场景展开,以航空货运订单管理为核心,通过构建不同的业务逻辑和功能需求,全面考察了 Java 基础语法、面向对象编程思想以及数据处理能力。在完成作业的过程中,我不仅巩固了课堂所学知识,还深刻体会到了理论与实践相结合的重要性,同时也对面向对象设计原则有了更为深入的理解和实际运用经验。
二、第一次大作业
(一)知识点
类的设计:在本次作业中,类的设计是构建整个系统的基石。客户类需要记录客户的基本信息,如姓名、联系方式等,为后续的订单操作提供主体标识;货物类则着重描述货物的属性,包括实际重量、体积等关键数据,这些信息直接影响到计费规则的计算;航班类承载了航班的相关信息,如航班号、起飞时间等,它与订单的关联体现了航空货运的业务流程;订单类作为核心枢纽,整合了客户、货物和航班等信息,负责协调各个类之间的交互,实现订单的创建、处理和管理。这些类的设计需要充分考虑类与类之间的关系,遵循面向对象的设计原则,确保代码的高内聚、低耦合。
计费规则计算:计费规则的计算是本次作业的难点之一。首先要根据货物实际重量和体积重量确定计费重量,体积重量通过货物体积除以 6000 来计算,然后取实际重量和体积重量中的较高者作为计费重量。确定计费重量后,采用分段计算方式确定费率并计算基础运费,即基础运费等于计费重量乘以费率。这一过程需要精确的逻辑判断和数值计算,对编程能力和对业务规则的理解都提出了较高要求。例如,在处理不同重量段的费率变化时,需要使用条件判断语句进行准确的逻辑分支处理,以确保运费计算的准确性。输入输出处理:输入输出处理是用户与程序交互的桥梁。按照特定顺序从键盘接收客户、货物、航班、订单等信息,这要求程序具备良好的输入验证机制,确保接收的数据符合规定的格式和范围。同时,按规定格式输出订单信息报表及货物明细报表,涉及输入输出流相关知识
面向对象设计原则:本次作业全面考核了单一职责原则、里氏代换原则、开闭原则、合成复用原则。单一职责原则要求每个类只负责一项职责,避免类的功能过于复杂,例如客户类只负责客户信息的管理,货物类专注于货物属性的处理,这样的设计使得代码结构更加清晰,易于维护和扩展;里氏代换原则确保子类可以替换父类,在类的继承关系中,子类的行为应与父类保持一致,保证程序的稳定性;开闭原则强调对扩展开放,对修改关闭,在后续功能扩展时,可以通过增加新的类或方法来实现,而无需修改现有稳定的代码;合成复用原则鼓励通过组合和聚合关系来实现代码复用,而不是过度使用继承,提高代码的灵活性和可维护性。
(二)题量
本次大作业虽然仅为单个题目,但涵盖的内容极为丰富。从信息输入环节开始,需要依次接收客户、货物、航班和订单的详细信息,每个信息模块都包含多个数据字段,需要进行细致的输入处理;在数据处理阶段,要完成复杂的计费规则计算和各类之间的逻辑交互;最后在报表输出环节,要生成规范的订单信息报表和货物明细报表。此外,还需要严格遵循多种面向对象设计原则,对代码进行优化和重构。因此,整体题量较大,需要花费大量的时间和精力进行分析、设计和编码。
(三)难度
本次大作业的难度定位为中上等,比起之前的电梯还是简单了很多。它要求实现各类的设计与交互,这需要对面向对象编程有扎实的理解,能够准确把握类之间的关系和交互逻辑;准确处理复杂计费规则,涉及到数学计算和逻辑判断,需要仔细分析业务需求,确保计算的准确性;同时还要遵循多种面向对象设计原则,将理论知识应用到实际代码中,这对知识的综合运用能力有一定要求。虽然每个知识点都具有一定的挑战性,但通过合理的时间规划和逐步分析,结合课堂所学知识和查阅相关资料,最终能够顺利完成作业,在这个过程中,自身的编程能力和问题解决能力得到了有效的锻炼和提升。


优点
结构较为清晰:从类和接口数量(6个)以及每个类的方法数(7.00 )来看,代码进行了一定程度的模块化设计,将功能分散到不同类和方法中,便于理解和维护,在一定程度上符合面向对象编程思想。
方法规模适中:每个方法平均语句数为2.95 ,说明大部分方法的逻辑相对简洁,没有出现方法体冗长、功能过度集中的情况,这有利于代码的可读性和可测试性。
缺点
存在复杂方法:明确标识出Rate.getRateBvWeight() 方法较复杂,行号为220 ,可能存在逻辑过于复杂、嵌套过多等问题,影响代码的可维护性和可扩展性,也不利于代码审查和调试。
代码深度问题:虽然每个方法平均语句数不多,但从柱状图看,存在一定数量较深嵌套(深度为2及以上 )的代码块,过深的嵌套会使代码逻辑难以理解,增加出错风险,且修改时牵一发而动全身。

三、第二次大作业
(一)知识点
类的设计:在第二次大作业中,类的设计在第一次的基础上进一步扩展和深化。除了客户类、货物类、航班类、订单类外,新增了支付方式类,用于处理不同的支付场景,如现金支付、在线支付等。客户类型细分为个人和集团,个人客户和集团客户在业务需求和优惠政策上存在差异,通过继承客户类,实现不同类型客户的特有属性和行为;货物类型也拓展为普通、加急、危险三种,每种货物类型在运输要求、计费规则等方面各不相同,同样通过继承货物类来实现差异化设计。这些类的设计更加复杂,需要考虑更多的业务逻辑和类之间的关联关系,以确保系统的完整性和可扩展性。
继承与多态:继承与多态是本次作业的核心知识点之一。通过继承,个人客户类和集团客户类继承了客户类的基本属性和方法,并根据自身特点重写或扩展了相关方法,如在计算运费时,个人用户享受 9 折优惠,集团用户享受 8 折优惠,通过重写运费计算方法实现了不同客户类型的差异化处理;货物类的继承同样如此,普通货物、加急货物和危险货物继承了货物类的基本属性,同时根据各自的特性实现了不同的运输和计费逻辑。多态的应用使得程序在运行时能够根据对象的实际类型动态调用相应的方法,提高了代码的灵活性和可维护性。例如,在订单处理过程中,无论客户是个人还是集团,货物是普通还是加急,都可以通过统一的接口调用相关方法,系统会根据对象的实际类型自动执行正确的业务逻辑。
计费规则计算:计费规则计算在本次作业中变得更加复杂。除了要根据货物实际重量和体积重量确定计费重量(计算方式与第一次作业相同)外,还需要依据货物类型、客户类型计算基础运费。基础运费的计算公式为基础运费 = 计费重量 × 费率 × 折扣率,其中折扣率根据客户类型而定,个人用户为 9 折,集团用户为 8 折。此外,不同货物类型可能还存在特殊的计费规则,如加急货物可能需要额外收取加急费用,危险货物的费率可能会更高等。这些复杂的计费规则需要在代码中进行细致的逻辑处理,确保运费计算的准确性和合理性。
输入输出处理:输入输出处理的要求与第一次作业类似,但由于类的设计更加复杂,数据量和业务逻辑的增加,使得输入输出的处理难度也相应提高。在输入环节,需要更加严格地验证输入数据的有效性,确保不同类型的客户、货物等信息都能准确无误地录入系统
面向对象设计原则:本次作业在面向对象设计原则的考核上更加全面,除了第一次作业涉及的单一职责原则、里氏代换原则、开闭原则、合成复用原则外,还新增了依赖倒转原则。依赖倒转原则强调高层模块不应该依赖低层模块,二者都应该依赖抽象,抽象不应该依赖细节,细节应该依赖抽象。在代码实现中,通过定义接口和抽象类,使得各个类之间的依赖关系更加清晰和稳定,提高了系统的可维护性和可扩展性。例如,订单类不直接依赖具体的客户类和货物类,而是依赖它们的抽象接口,这样在后续扩展客户类型或货物类型时,订单类的代码无需进行大规模修改,只需要实现新的接口即可。
(二)题量
本题同样仅设一道题目,但题量相比第一次作业有过之而无不及。在信息输入方面,需要依次完成客户、货物、航班、订单等信息的输入,并且由于客户和货物类型的细分,每个信息模块的输入内容更加丰富;在数据处理阶段,要进行复杂的继承关系处理、多态方法调用以及复杂的计费规则计算,涉及到大量的逻辑判断和数据运算;在报表输出环节,要按照规定格式输出包含更多详细信息的订单信息报表与货物明细报表。同时,还要严格遵循多种面向对象设计原则,对代码进行反复的优化和重构。整个作业流程繁琐,任务量大,需要投入更多的时间和精力进行深入的分析和开发。
(三)难度
本次大作业的难度被评定为较难。但还是比电梯简单很多,它要求综合运用类的设计、继承与多态、计费规则计算、输入输出处理等多方面的知识,不仅要合理设计各类别及其交互逻辑,确保系统的稳定性和可靠性,还要精准处理复杂的计费规则,考虑到各种业务场景和特殊情况;同时,要严格践行单一职责原则、里氏代换原则、开闭原则、合成复用原则、依赖倒转原则等面向对象设计原则,这对知识的深度理解与综合运用能力提出了极高的要求。在完成作业的过程中,需要不断地查阅资料、思考分析和调试代码,克服重重困难,最终实现系统的功能需求。通过本次作业,我对 Java 编程的理解和应用能力得到了质的提升,也更加深刻地认识到了面向对象编程的强大魅力和实际价值。



缺点
代码复杂度高:
最复杂方法RateCalculator.calculateRate() 复杂度达 14 ,其位于 116 行,可能逻辑冗长、嵌套或条件判断复杂,不利于理解和维护。
平均复杂度 2.05,最大块深度达 4 ,平均块深度 2.20 ,柱状图也显示深度为 1 - 4 的代码块语句较多,说明代码存在较多嵌套,结构复杂,易出错且难调试。
分支语句占比高:分支语句百分比为 16.8% ,意味着代码中条件判断逻辑较多,可能使程序执行逻辑错综复杂,降低可读性。
方法平均语句多:平均每个方法有 6.89 条语句 ,部分方法可能功能聚合度过高,可考虑拆分以提升可读性和可维护性。

四、总结

  1. 学习收获
    1.1面向对象编程核心原则领悟
    单一职责原则贯彻:深刻理解到每个类或方法应专注于单一任务。像InputHandler类专心处理输入操作,OrderProcessor类则聚焦于订单处理。如此划分职责,让代码结构清晰明了,维护起来更加便捷,避免了因功能混杂导致的代码混乱。
    懂得通过扩展来增添新功能,而非直接修改原有代码。以RateStrategy接口为例,当出现新的货物类型时,只需实现该接口来添加新策略,而不用改动原有的费率计算逻辑,有效保障了代码的稳定性与可扩展性。
    认识到高层模块不应依赖低层模块的具体实现,而是依赖抽象。比如OrderProcessor依赖抽象的RateCalculator接口,降低了模块间的耦合度,使系统更具灵活性和可维护性。

1.2 代码组织技巧掌握
清晰划分输入、处理、输出层次,将输入层、业务层、展示层分离。这种分层架构让各部分功能职责明确,提高了代码的可读性与可维护性,不同层次间的交互也更加规范有序。
使用专门的数据类,如OrderRequest、GoodsInfo,替代分散的变量。这样不仅使数据管理更加集中高效,还增强了数据的安全性,减少了数据在传递过程中出错的可能性。
将易变的规则,如费率、折扣等,从代码中抽取出来。通过这种方式,当规则发生变化时,无需修改大量代码,只需调整配置文件,提升了代码的适应性和可维护性。

1.3 开发实践经验积累
先实现核心功能,比如基础运费计算,再逐步迭代增强功能,像添加不同货物类型的运费计算规则、引入折扣计算等。这种开发方式能快速搭建起系统雏形,逐步完善功能,降低开发风险。

  1. 有待加强之处
    2.1 编码能力提升
    设计模式应用生疏:在面对复杂业务场景时,不能迅速准确地选择合适的设计模式来优化代码结构,提高代码的可复用性和可维护性。
    接口设计欠缺考量:在定义抽象接口时,对扩展性的考虑不够周全。例如,在最初设计接口时,未充分预估到可能会出现多种支付方式,导致后续增加功能时需要对接口进行较大改动,影响了开发效率和代码的稳定性。
    代码复用性不:代码中存在重复计算逻辑,如多次进行体积重量的计算。这不仅增加了代码量,还可能因修改不统一而产生错误,降低了代码的质量和可维护性。