NCHU-有关航空货运管理系统的Blog

一.前言
1.知识点: 相对于上一次电梯调度问题,此次航空货运管理系统在算法上的需求少了许多,但在结构的设计上增加了更多的要求,例如对于单一职责原则、里氏代换原则、开
闭原则以及合成复用原则、依赖倒转原则的符合使用,在经过两次迭代后也对于抽象类,接口,继承与多态的使用做了明确要求。
2.题量:虽说设计的要求变多,但若是掌握要求原则,那么此次的题量并不是很大,可是题目的需求体量摆在那里,在设计时还是要费不少功夫,在短时间内完成还是有不小的难度,更何况要求的变量还是十分多的情况下。
3.难度:在难度方面,与电梯调度问题相比:此题在设计逻辑上的难度大幅度降低了,但相对的,在类图的设计上和结构的布局上的难度有所提升。此问题在抽象类的设计上体现的尤为明显,如果不对题目需求仔细思考的话,对于抽象类的选择将会变的十分困难,但如果沉下心来思考,此次的整体难度还是略低于上次的电梯调度问题。
二:设计与分析
1.第八次题目集:
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计,具体说明参看说明文件。
OO第九周作业题目说明.pdf

输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。

客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:

航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
微信支付金额:

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
注:输出中实型数均保留1位小数。

输入样例:
在这里给出一组输入。例如:

10001
郭靖
13807911234
南昌航空大学
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
输出样例:
在这里给出相应的输出。例如:

客户:郭靖(13807911234)订单信息如下:

航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
微信支付金额:3350.0

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 发电机 80.0 25.0 2000.0
2 信号发生器 45.0 30.0 1350.0

某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。
本次作业主要考虑货物重量/体积,以下是具体的计算方式和关键要点:
一、计费重量的确定
 空运以实际重量(Gross Weight)和体积重量(Volume Weight)中的较高者作为计费重量。
 计算公式:
  体积重量(kg) = 货物体积(长×宽×高,单位:厘米)÷ 6000
示例:
 若货物实际重量为 80kg,体积为 120cm×80cm×60cm,则:
  体积重量 = (120×80×60) ÷ 6000 = 96kg
  计费重量取 96kg(因 96kg > 80kg)。

类图设计和代码复杂度分析分别如下:



由代码复杂度来看:
分支语句占比(Percent Branch Statements):3.8% ,说明代码中条件判断等分支逻辑不算多,代码逻辑相对较线性。
方法调用语句数(Method Call Statements):30 ,反映代码模块间的交互频繁程度。
类和接口数量(Classes and Interfaces):10 个,表明代码有一定的抽象和封装层次。
平均每个类的方法数(Methods per Class):6.8 ,说明类的功能相对丰富。
平均每个方法的语句数(Average Statements per Method):2.65 ,方法粒度相对较小,可能功能比较单一。
最复杂方法的行数(Line Number of Most Complex Method ):347 ,是Main.main() ,这个方法比较复杂,行数较多,可能承担了较多功能。
最大复杂度(Maximum Complexity):9 ,说明存在一定复杂度的代码段 。
最深代码块行数(Line Number of Deepest Block ):369 ,最大代码块深度(Maximum Block Depth):4 ,平均代码块深度(Average Block Depth):1.71 ,平均复杂度(Average Complexity):1.16 ,反映代码嵌套和复杂程度的不同维度指标 。
由类图来看:
类的职责划分较为清晰,每个类专注于自身相关的业务功能,符合面向对象设计中单一职责原则。
通过继承机制,在Good类及其子类中实现不同的费率计算,体现了面向对象的多态性,便于扩展和维护不同的费率规则。
类之间的关联关系明确,能够清晰地反映出业务中的实体关系,有助于理解业务逻辑。
但是缺乏对异常处理和事务管理等方面的设计考虑,在系统健壮性方面存在不足。
2.第九次题目集:
某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包
括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。
本次作业主要考虑货物重量/体积,以下是具体的计算方式和关键要点:
一、计费重量的确定
空运以实际重量(GrossWeight)和体积重量(VolumeWeight)中的较
高者作为计费重量。
计算公式:
体积重量(kg)= 货物体积(长×宽×高,单位:厘米)÷6000
示例:
若货物实际重量为80kg,体积为120cm×80cm×60cm,则:
体积重量 =(120×80×60)÷6000=96kg
计费重量取96kg(因96kg>80kg)。
二、基础运费计算
1
费率(Rate):航空公司或货代根据航线、货物类型、市场行情等制定(如
CNY30/kg)。本次作业费率与货物类型有关,货物类型分为普通货物、危险货
物和加急货物三种,其费率分别为:
计算公式:基础运费 = 计费重量 × 费率 × 折扣率
其中,折扣率是指不同的用户类型针对每个订单的运费可以享受相应的折扣,
在本题中,用户分为个人用户和集团用户,其中个人用户可享受订单运费的9
折优惠,集团用户可享受订单运费的8折优惠。
三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场,航班降落机场,航班日期,航班最大载
重量)
2
客户填写货运订单并进行支付,需要提供如下信息:
 客户信息(姓名,电话号码等)
 货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
 运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
 支付方式(支付宝支付、微信支付、现金支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。

客户类型[可输入项:Individual/Corporate]
客户编号
客户姓名
客户电话
客户地址
货物类型[可输入项:Normal/Expedite/Dangerous]
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
支付方式[可输入项:Wechat/ALiPay/Cash]
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:

航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
[微信/支付宝/现金]支付金额:

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
注:输出中实型数均保留1位小数。

输入样例:
在这里给出一组输入。例如:

Corporate
10001
郭靖
13807911234
南昌航空大学
Expedite
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
ALiPay
输出样例:
在这里给出相应的输出。例如:

客户:郭靖(13807911234)订单信息如下:

航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
支付宝支付金额:4360.0

货物明细如下:

明细编号 货物名称 计费重量 计费费率 应交运费
1 发电机 80.0 40.0 3200.0
2 信号发生器 45.0 50.0 2250.0
类图设计和代码复杂度分析分别如下:



由代码复杂度来看:
代码行数(Lines):486 行,相比常见小型项目略多,有一定规模。
语句数(Statements):334 条,反映代码实际执行操作数量。
分支语句占比(Percent Branch Statements):9.0% ,比一般线性代码逻辑分支略多,意味着条件判断等逻辑稍复杂。
方法调用语句数(Method Call Statements):53 ,表明模块间交互较频繁。
类和接口数量(Classes and Interfaces):9 个,有一定的抽象和封装层次。
平均每个类的方法数(Methods per Class):7.78 ,类的功能较丰富。
平均每个方法的语句数(Average Statements per Method):3.17 ,方法功能相对单一,粒度较小。
最复杂方法的行数(Line Number of Most Complex Method ):392 ,是Main.main() ,该方法承担较多功能,可读性和维护性差。
最大复杂度(Maximum Complexity):9 ,存在较复杂代码段。
最深代码块行数(Line Number of Deepest Block ):417 ,最大代码块深度(Maximum Block Depth):4 ,平均代码块深度(Average Block Depth):1.82 ,平均复杂度(Average Complexity):1.51 ,反映代码嵌套和整体复杂程度。
注释行占比(Percent Lines with Comments):0.0% ,缺少注释,严重影响代码可读性和可维护性。
由类图来看:
类的职责划分相对清晰,每个类专注于自身业务范畴,符合面向对象设计的单一职责原则。
利用继承机制实现货物类型的差异化处理,体现多态性,便于系统扩展新的货物类型。
类之间关系明确,能够较好地反映业务中的实体联系,有助于理解业务流程。
但是缺乏对异常处理、事务管理等系统健壮性方面的设计考虑。
三:踩坑心得
此次与上次最大的区别便是对于审题的要求大幅度提升,如果上一次的是对于算法的考验,那么此次便是对题目阅读理解的测验,由于初次对于题目的大意判断,盲目书写代码,未能完全满足题目需求,导致了后面修改代码使得落魄狼藉,最直接的体现便是抽象类的设计,最开始我是没有考虑抽象类的,结果在再次审题时发现,使我不得不对代码进行大幅度修改。虽说在初次的题目中便遭遇如此挫折,但我在第二次的迭代中依旧犯了类似的错误,其中最大的便是pay类的设计,又一次的忽略需求使我后续的修改又遇到了问题,被迫进行大幅度调整。其次,在编写中的小问题还有,自己设计的类逻辑无法匹配题目需求(例如第二次的输出金额和应支付金额的不同,但我误将两者混为一谈使得我设计的类不得不分为两部分),总的来说,此次最大的坑便是仔细审题!仔细审题!仔细审题!尽管对于知识点已了然于心,但以为不熟题目而最后大败而归(是指时间耗时上的之多),两次的题目虽全部正确,但依旧有一定的挫败感。
四:改进建议
两次的代码都有一个共同的问题:注释太少了!这不仅不利于后续的迭代,也不利于优化和修改,在每个类和重要方法前添加注释,说明类的功能、方法的作用、参数含义和返回值意义。
Main类目前与多个类直接交互,可考虑引入外观类,对复杂的子系统(如航班、货物、客户等业务逻辑组合)进行封装,简化Main类调用逻辑,降低耦合度。
对于第二次迭代的问题:
Good类及其子类GoodNormal、GoodExpensive、GoodDangerous 计算交易费率(dealRate )和交易金额(dealMoney )的逻辑可利用策略模式。将不同货物类型的计算逻辑封装成独立策略类,使代码更具扩展性和可维护性。例如,创建RateCalculationStrategy接口,各子类实现该接口的calculateRate方法。
对于第一次的问题:
方法中存在重复计算,例如计算Rate时反复使用了费用的计算,应避免重复计算。
五:总结
对比与上次的代码,进步是有的,首先与上次相比,此次的两次作业都顺利完成,我也从中意识到了在数据多的情况下,类图的设计是多么有必要的,还有看似抽象的抽象类在实际使用下有多么的方便,一个好的类图设计是十分甚至九分的重要。万万不可在看题目的同时写代码,这只会使我们万劫不复,而且我也在此次意识到了理论到实践的区别之大,在书上看起来有多么简单,在实践上就有多么无奈。

posted @ 2025-05-25 14:57  tsomrenni  阅读(43)  评论(0)    收藏  举报