航空货运管理系统8-9次Blog作业
航空货运管理系统8-9次Blog作业
一. 前言
关于本次的航空航天管理系统的作业,第八次的作业只要考虑的是类的相关设计,其他方面并不难,对于刚开始写长代码的时候,我的开始是不知道从那开始下手,然后就硬着头皮写,把该写的都写了就慢慢可以看到整个框架了。第二次题目集就在原有的功能下,增加了继承和多态的使用,实现了功能的扩展。两次题目集都严格遵守单一职责原则、里氏代换原则、开闭原则以及合成复用原则。
二.设计与分析
题目8
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计
点击查看输入格式
客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
点击查看输出格式
客户:姓名(电话)订单信息如下:
-----------------------------------------
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
微信支付金额:
货物明细如下:
-----------------------------------------
明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
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)。二、基础运费计算费率(Rate):航空公司或货代根据航线、货物类型、市场行情等制定(如CNY 30/kg)。本次作业费率采用分段计算方式:

三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信
息报表及货物明细报表。

代码说明:
- 代码结构与复杂度分析
雷达图显示以下关键指标:
每类方法数 (Methods/Class):平均值 3.4,属于合理范围
平均复杂度 (Avg Complexity):1.40,较低
平均深度 (Avg Depth):1.42,嵌套层级较浅
注释率 (% Comments):未明确显示,但代码中注释较少
问题点:
CargoOrder.getTotalFreight() 方法复杂度为 2,是最复杂的方法之一
缺少类级和方法级注释,代码可读性受影响
类之间的职责划分清晰,但部分方法可进一步抽象
类图分析
CargoOrder 与 Customer:CargoOrder 类与 Customer 类是一对一关联,一个货运订单对应一个客户 。
CargoOrder 与 Goods:CargoOrder 类与 Goods 类是一对多关联(0..* ),一个货运订单可以包含零个或多个货物。
CargoOrder 与 Flight:CargoOrder 类与 Flight 类是一对一关联,一个货运订单对应一趟航班
从上面可以看出我的代码类设计还是有点牵强,职责的分工还是不适合清晰,以下是一些可以加以改进的点,
重构重点:
若getTotalFreight()逻辑复杂,可提取运费计算部分到独立方法,降低块深度。
维护性:
深度3的代码块(如行号140)建议添加注释或拆分条件判断。
扩展性:
当前类适合新增简单方法,但需保持复杂度趋势稳定。
题目9
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息
点击查看输入格式
客户类型[可输入项:Individual/Corporate]
客户编号
客户姓名
客户电话
客户地址
货物类型[可输入项:Normal/Expedite/Dangerous]
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
支付方式[可输入项:Wechat/ALiPay/Cash]
点击查看输出格式
客户:姓名(电话)订单信息如下:
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
[微信/支付宝/现金]支付金额:
货物明细如下
明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
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
二、基础运费计算2
费率(Rate):航空公司或货代根据航线、货物类型、市场行情等制定(如
CNY 30/kg)。本次作业费率与货物类型有关,货物类型分为普通货物、危险货
物和加急货物三种,其费率分别为:

计算公式:基础运费 = 计费重量 × 费率 × 折扣率
其中,折扣率是指不同的用户类型针对每个订单的运费可以享受相应的折扣,
在本题中,用户分为个人用户和集团用户,其中个人用户可享受订单运费的 9
折优惠,集团用户可享受订单运费的 8 折优惠。
三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场,航班降落机场,航班日期,航班最大载
重量)3
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
支付方式(支付宝支付、微信支付、现金支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信
息报表及货物明细报表。


类图分析:
CargoOrder(货运订单)
关键属性:订单ID、日期、货物列表(ArrayList
核心方法:
getTotalWeight():计算货物总重量。
getActualPayment():结合用户折扣和支付方式计算实付金额(需联动User和PaymentMethod)。
User(用户)
继承关系:
IndividualUser(个人用户)和CorporateUser(企业用户)需实现不同的getDiscountRate()逻辑。
Goods(货物)
关联枚举:GoodsType(如“易碎品”“普通货物”)可影响运费计算规则。
PaymentMethod(支付方式)
多态设计:子类(微信、支付宝、现金)需实现统一的payAmount(double)接口。
- 方法复杂度与异常点
最高复杂度方法:
Main.getType()(复杂度=4,语句数=79,块深度=4)
方法写的可能过于复杂化了,有些逻辑可能不高简洁,尤其是Goods.getRate() 高语句数(31)、高复杂度(4)
在单一职责方面做的不够好。
2.状图显示:
88.7%语句集中在深度1-2(安全区)。
深度≥4的语句占5%(需关注Main.getType()的8条深度4语句)。
重构重点:通过卫语句(Guard Clauses)或早返模式降低嵌套。
三踩坑心得:
我一开始对于输入和输出的想法是在每个需要的类写一个方法来,再在按顺序依次输出,后来决定不如卸载Main里简洁,就都放在Main里面了。
2其次是输入格式的要求,因为在nextline前应该要消耗掉换行符的而我没有。为此查了些资料
在Java中使用Scanner类读取输入时,nextInt()、nextDouble()等方法只会读取数值本身,而不会读取输入行末尾的换行符(\n)。这个换行符会留在输入缓冲区中。
当接下来使用nextLine()读取字符串时,nextLine()会读取缓冲区中直到换行符的内容。由于之前有换行符留在缓冲区中,nextLine()会立即读取到这个换行符,返回一个空字符串,而不是我们期望的下一个输入内容。
因此,在调用nextInt()、nextDouble()等数值读取方法后,通常需要添加一个nextLine()来"消耗"掉这个换行符,以确保后续的nextLine()能正确读取到用户输入的内容。
在Java中使用Scanner类时,除了nextInt()之后需要消耗换行符外,还有以下几种常见情况也需要这么做:
读取其他数值类型后:
nextDouble()
nextFloat()
nextLong()
nextShort()
nextByte() 这些方法都会在读取数值后留下换行符。
读取单个单词后:
next()方法只读取一个单词(以空格分隔),也会留下换行符
读取布尔值后:
nextBoolean()方法读取布尔值后也会留下换行符
混合使用不同读取方法时: 当交替使用数值读取方法和nextLine()时,通常需要在数值读取后添加nextLine()来消耗换行符
在于:使用nextLine()读取字符串时,nextLine()会读取缓冲区中直到换行符的内容。由于之前有换行符留在缓冲区中,nextLine()会立即读取到这个换行符,返回一个空字符串。

四 改进建议
第八次题目我是把用于输出的代码全写在了Main方法里,当时觉得好看一些应该没什么,但其实这样做还是不利于后来的功能添加和完善的,于是在题目集九的时候我把他写进了类的方法里,(printOrderInfo)把关于支付方式写进了输出的后面,符合后来的单一原则的话最好还是全部写到应该方法里。
在方法上,比如Goods.getRate() 高语句数(31)、高复杂度(4),在于我写判断费率的时候用了很多if else,好的做法应该是策略模式 + 费率规则解耦,实例展示:
点击查看代码
// 1. 定义费率计算策略接口
public interface RateStrategy {
double calculateRate(Goods goods);
}
// 2. 实现具体策略(按货物类型拆分)
public class StandardRateStrategy implements RateStrategy {
@Override
public double calculateRate(Goods goods) {
return goods.getWeight() * BASE_RATE; // 简化后的核心逻辑
}
}
public class FragileRateStrategy implements RateStrategy {
@Override
public double calculateRate(Goods goods) {
return goods.getVolume() * FRAGILE_MULTIPLIER;
}
}
// 3. Goods类改造
public class Goods {
private RateStrategy rateStrategy; // 通过构造器或工厂注入
public double getRate() {
return rateStrategy.calculateRate(this); // 复杂度降为1
}
}
还有的点就是,写到时候没有一些必要的备注,后来发现前面有问题的时候就非常的不好找,尤其是后来看烦了后,让人找到头皮发麻,所幸的是代码不是很长花了一番功夫还是把错误找到了,所以在写代码的时候虽然当时看起来觉得可能没什么自己肯定能看懂的,最好的方式还是在必要的地方注释。
五 总结:
像在前沿里的说的一样,刚开始拿到题干的时候决定好复杂做不出来的样子,:客户类型、货物类型、航班载重、支付方式。这么多要我写的吗,感觉是挺心累的。最最最开始的其实是刚开始不知道从哪去下手是做难受的,感觉这么大的一个题干,我该从那开始下手呢,犹豫踟躇,我觉得做好的方法其实就是一步一步看题目然后先找到大的类,如果看不太懂也没关系,主要先把大的框架打出来然后可以再往下看,大不了就是不停的读题目,一直读着读着就看懂了。在类的设计的时候=看到个人用户和企业用户想着要不要用继承?还是直接写两个类?最终选了抽象类User,因为发现都要姓名、电话这些共同属性,看到货物还要分类型?普通、加急、危险品……费率,写了一堆ifelse。搞得一些麻烦了。
还有边界条件一定要测:比如重量=0、体积>实际重量、刚好等于最大载重等情况,这些往往但是关键点测试所在。最后的告知自己的建议就是,不要害怕,想想现在的题目并不会出的那么难,认真看下去,一遍在一变=遍,一步一步往下写,不怕错,不怕该往下写就好了。

浙公网安备 33010602011771号