Java两次航空货运管理系统blog
一、前言
在两次题目集的设计与实现中,我们完成了“航空货运管理系统”的基础版与扩展版开发。题目集从简单订单管理逐步升级为支持多类型货物、客户分类及支付方式的复杂系统,涉及知识点包括面向对象设计、集合框架应用、策略模式实现、输入输出处理等。以下从设计与分析、采坑心得、改进建议等方面展开详细探讨。
二、设计与分析
- 系统架构演进
题目集1(基础版):
核心类:Client(客户)、Air(航班)、Deal(订单)、Goods(货物)、Display(展示类)。
功能逻辑:
输入客户信息、货物列表、航班信息,校验航班载重能力。
货物计费逻辑:基于体积与重量的最大值计算计费重量,固定费率规则。
题目集2(扩展版):
新增特性:
货物分类:普通(Normal)、危险品(Dangerous)、加急(Expedite)。
客户类型:个人(Individual)与企业(Corporate),享受不同折扣。
支付方式:微信、支付宝、现金。
架构调整:
Goods类新增kindP(客户类型)和kindG(货物类型)属性。
Rate和Price类引入策略模式,动态计算费率与价格。
Display类增加支付方式字段,输出逻辑更复杂。
- 类图与模块交互
通过类图可见:
![]()
核心模块:
数据实体:Air管理航班信息,Goods存储货物属性,Deal关联订单与客户。
策略接口:Rateget(费率计算)、Priceget(价格计算)实现业务规则解耦。
展示层:Display聚合所有数据,负责格式化输出。

- 复杂度分析(基于截图数据)
题目集1复杂度(图2):
方法平均复杂度:2.1
最大深度:4
方法数/类:3.5
问题点:Goods.rateWeight()和Air.canHold()方法逻辑简单,但Display.display()因多数据聚合输出导致圈复杂度较高(值为5)。

题目集2复杂度(图3):
方法平均复杂度:3.8(↑80%)
最大深度:6(↑50%)
方法数/类:4.2(↑20%)
问题点:
Rate.rateGet()方法因多层switch-case分支,圈复杂度达8(图3中Max Complexity=8)。
Price.priceGet()需处理客户类型与货物类型组合,逻辑耦合度高。
- 关键代码解析
题目集2的动态费率计算:
java
class Rate implements Rateget {
@Override
public double rateGet(Goods good) {
double weight = good.rateWeight();
switch (good.getKindG()) {
case "Normal":
if (weight < 20) return 35;
else if (weight < 50) return 30;
else if (weight < 100) return 25;
else return 15;
case "Dangerous":
// 危险品费率规则
case "Expedite":
// 加急货物费率规则
default:
throw new IllegalArgumentException("Invalid goods type");
}
}
}
通过策略模式将费率规则与货物类型解耦,符合开闭原则。
题目集2的价格折扣逻辑:
java
class Price implements Priceget {
@Override
public double priceGet(Goods good, double rate) {
double discount = 1;
switch (good.getKindP()) {
case "Individual": discount = 0.9; break;
case "Corporate": discount = 0.8; break;
}
return rate * discount * good.rateWeight();
}
}
优化方向:
折扣策略可进一步抽象为DiscountStrategy接口,支持动态扩展。
三、采坑心得
- 输入顺序与参数传递错误
问题:在扩展版中,Main类输入kindP(客户类型)和kindG(货物类型)时,顺序与Goods构造函数参数不匹配,导致类型赋值错误。
解决:通过单元测试发现构造参数顺序应为kindP在前,调整输入代码:
java
Goods goods = new Goods(..., kindP, kindG); // 修正参数顺序
2. 接口设计冗余
问题:题目集1的Priceget接口仅支持priceGet(double, double),扩展版需传递Goods对象,导致接口方法爆炸(新增priceIGet())。
解决:重构接口为单一方法:
java
interface Priceget {
double calculatePrice(Goods good, double rate);
}
3. 数值精度丢失
问题:使用double存储电话号码(如13812345678)时,因浮点数精度丢失导致输出异常。
解决:将Client.phone和Deal.number改为String类型。
四、改进建议
使用策略模式解耦费率计算
问题:Rate.rateGet()方法包含多层分支,维护困难。
方案:为每类货物定义独立策略类:
java
interface RateStrategy {
double calculateRate(double weight);
}
class NormalRate implements RateStrategy {
public double calculateRate(double weight) { /* 普通费率逻辑 */ }
}
增强输入校验
问题:未校验支付方式输入合法性。
方案:在Main类中增加正则匹配:
java
if (!p.matches("Wechat|ALiPay|Cash")) {
throw new InputMismatchException("Invalid payment type: " + p);
}
模块化展示逻辑
问题:Display.display()方法过长(40+行),圈复杂度高。
方案:拆分为OrderHeaderPrinter、GoodsDetailPrinter等子模块。
五、总结
- 学习收获
设计模式应用:通过策略模式、接口隔离原则,提升了代码扩展性。
调试能力:通过单元测试与边界条件覆盖,显著减少运行时错误。
代码质量意识:复杂度分析工具的使用帮助识别高风险代码。
结语
两次题目集的开发实践,我不仅巩固了Java编程基础,更深刻体会到系统设计的重要性。从基础版到扩展版的开发,像是搭积木变造房子。一开始简单明了,后来加入货物分类、折扣和支付方式,挑战倍增。踩过输入顺序颠倒、数值精度丢失的坑,也学会了用模块化设计让代码更灵活。
posted on 2025-05-23 12:51 UnKn0wN__XD 阅读(31) 评论(0) 收藏 举报

浙公网安备 33010602011771号