前言
-
知识点
- 面向对象设计原则
- SRP(单一职责原则):将订单处理、支付计算、打印等功能分离到不同类
- OCP(开闭原则):通过抽象类实现支付方式和费率计算的扩展性
- LSP(里氏替换原则):Customer父类与子类的继承关系设计
- Java特性
- 抽象类与接口的应用
- 集合框架(List)的使用
- 面向对象设计原则
-
题量:相对上次题目,这次主要是进行类设计以及对面向对象设计原则的遵循,因此题量不大
-
难度情况:相对之前写的代码,类的结构复杂了一些,设计起来相对困难,但是总体来说难度不大
设计与分析
下文的每一次航空货运的题目的代码将分为两个部分分析
分别是设计方法与模式以及代码相关数据分析
第一次航空货运管理系统代码分析
设计方法与模式
题目集8的航空货运管理系统划分为以下几个核心类:
- Customer类:
封装客户基本信息:ID、姓名、电话、地址
提供完整的getter和setter方法
作为Order类的组合部分 - Goods类:
管理货物信息:货物ID、名称、长宽高尺寸、重量
核心方法getSpendWeight()实现了体积重量计算逻辑
计算体积重量(长×宽×高/6000)
体积重量与实际重量取较大值作为计费重量 - Flight类:
记录航班信息:航班号、起降机场、日期、最大载重、当前载重
关键方法IsCanCarry()检查航班剩余载重能力
addLoad()方法更新航班当前载重 - Order类:
系统核心类,整合客户、货物和航班信息
包含订单基本信息:订单ID、日期、收发件人信息
calculateTotalWeight()方法计算订单总重量
采用组合关系关联Customer、Goods列表和Flight - 支付系统:
(这个部分中的支付类在这次题目中其实并未用到)
抽象类Payment定义支付接口
AliPay和WeChatPay实现具体支付方式
遵循开闭原则,便于扩展新的支付方式
订单处理类:
IsOrderValid提供订单验证逻辑
OrderProcessing处理订单核心流程
OrderPrinter负责订单信息打印输出
设计原则 单一职责原则(SRP)分析: Customer类:只负责客户信息管理,职责单一 Goods类:只处理货物信息和重量计算,职责明确 Flight类:专注航班信息和载重管理,不涉及其他逻辑 Order类:虽然整合多个信息,但主要职责是订单数据管理 OrderPrinter类:专门处理打印逻辑,符合SRP 开闭原则(OCP)分析: Payment抽象类支持扩展新支付方式不影响现有代码 航班载重验证逻辑封闭修改但支持扩展(通过IsOrderValid) 里氏替换原则(LSP)分析: 所有Payment子类(AliPay/WeChatPay)完全替代父类行为 依赖倒置原则(DIP)分析: OrderProcessing依赖抽象(Order/Flight),不依赖具体 迪米特法则(LoD)分析: OrderProcessing与Order/Flight的交互符合LoD
主要改进点总结:
OrderPrinter:
深入Order对象内部获取数据
硬编码费率计算逻辑导致解耦合做的不好
Order没有提供聚合数据方法供打印使用
将代码逻辑从Order移到专门的处理类
整体来看,代码在SRP和LSP方面做得较好
但在OCP、DIP和LoD方面有较多改进空间
特别是订单打印和主程序部分。
代码相关数据分析
指标分析
| 指标名称 | 数值 | 分析评价 |
|---|---|---|
| 总行数 | 421 | 中等规模代码 |
| 语句数 | 201 | 语句密度47.7%,属于正常范围 |
| 分支语句百分比 | 2.0% | 条件逻辑较少,控制流简单 |
| 方法调用语句数 | 26 | 方法调用占比12.9%,耦合度较低 |
| 注释行百分比 | 0.5% | 这个确实有点少了,但是因为确实逻辑不复杂,修改也较少,意义不大 |
| 类/接口数 | 10 | 面向对象设计合理 |
| 每类方法数 | 5.80 | 类职责分配适中 |
| 方法平均语句数 | 1.74 | 似乎有点短了 |
复杂度分析
| 复杂度指标 | 数值 |
|---|---|
| 最复杂方法 | Goods.getSpendWeight() |
| 最大复杂度 | 3 |
| 最深块行号 | 105 |
| 最大块深度 | 3 |
Kiviat图关键维度
代码质量六维评估
注释率, 方法数/类, 平均复杂度, 平均深度, 最大深度, 最大复杂度
"当前值" : [0.5, 5.8, 1.2, 1.5, 3, 3]
"推荐值" : [15, 5, 2, 2, 4, 4]
总而言之,这次的代码主要是锻炼了面向对象的设计思维,题目集8代码体现出设计模式的雏形。主要需要加强:
更明确地应用经典设计模式
遵循SOLID原则改进架构
减少模块间耦合
提高扩展性和维护性
这些改进将使系统更好地应对需求变化,提升代码质量。
下面是SourceMonitor给出的分析以及本次代码的类图


第二次航空货运管理系统代码分析
设计方法与模式
这里主要详细解释一下第一二次代码的设计思路的变化
在设计这个航空货运管理系统时,我首先思考如何将实际转化为代码结构(即为其类间关系)。
我从最基本的物品开始,把客户、货物和航班分别设计成Customer、Goods和Flight类。
我确保每个类只做一件事,比如Goods类专门处理货物信息和重量计算。
然后考虑订单管理,设计了Order类来整合这些物品。
但很快发现如果把所有代码逻辑都塞进Order类会让它变得臃肿。
于是把订单处理逻辑拆分到OrderProcessing类。
打印功能交给OrderPrinter类。
在实现支付功能时,不同的支付方式要求可以灵活扩展。
所以采用了继承的方式,定义Payment抽象类让AliPay和WeChatPay分别实现。
过程中遇到的最大问题是OrderPrinter类承担了太多职责。
它既负责打印又计算费率,这违反了单一职责原则。
后来我通过将费率计算逻辑分离出来解决了这个问题。
整个设计过程让我深刻体会到:
从最初简单地把实际问题的关系转化成代码关系,到后来有意识地应用设计原则来改进结构。
这是一个很有价值的学习过程。
代码相关数据分析
这次代码主要是对上次进行了一些功能上的扩展,在整体的数据表现上差别很小(得益于设计原则的应用,实际的代码差别也很小),这里就只给出SourceMonitor的分析图和类图


踩坑心得
这两次代码给我带来的最大收获就是让我意识到面向对象设计模式的产生原因,其实最本质上的原因是提高工作效率,如果只是一时偷懒,不去考虑各种类之间的关系,不去好好设计,最后如果运气不好,还是要花上更多的时间到代码的修改与Debug上,虽然这两次题目没有踩这个坑,但是在前段时间我确实是深受其害,总之,认真的设计好代码再编写在大多数情况下才能真正的偷懒
改进建议
整体上来说没有大问题,但是在功能的分工上可以更清楚,让模块化抽象化的思想更加明显
总结
通过本次航空货运管理系统的两次题目,我在面向对象设计和设计模式应用方面获得了重要提升,这些经验让我理解到,合理运用设计模式不仅能提高代码质量,更能使一个系统的功能扩展更加方便。实际上我做第二次题目花的时间较短,基本上只做了简单的修改,就完成了题目,这也正是得益于对设计原则的遵守。在之后的学习与工作中,我也将利用这些原则来保证学习的效率和代码的质量。
浙公网安备 33010602011771号