第2次blog作业

前言
本次航空货物管理系统设计与实现实验采用迭代开发模式,在实践过程中系统掌握了 Java 面向对象编程核心技术,包括类与对象构建、数据封装规范,熟练运用 ArrayList、HashMap 等集合框架进行数据管理,并通过抽象类和接口深入理解继承与多态机制,运用工厂模式、策略模式优化系统架构。同时,借助 try-catch 及自定义异常增强程序稳定性,严格遵循单一职责、里氏代换等设计原则进行功能模块拆分与代码设计,保障数据安全并降低模块耦合度。题目集 8-9 的 5 道实验题目虽具挑战性,但通过综合运用多种技术与设计模式,不仅深化了对面向对象设计原则的理解,也有效提升了复杂系统架构设计能力,为后续软件开发积累了实践经验。
设计与分析
第一次迭代作业
类图:
表:

分析:分支语句占比:分支语句占比 4.7% ,意味着代码中条件判断逻辑不算特别多,代码执行路径相对较为直接。
方法调用语句数:有 33 条方法调用语句,说明代码通过方法调用实现功能模块化,有一定的结构设计。
注释行占比:注释行占比为 0% ,这是不好的现象,缺乏注释会使代码可读性变差,后期维护困难。
类与方法相关指标
类与接口数量:有 9 个类和接口,代码进行了一定程度的模块化设计,将不同功能封装在不同类型中。
平均方法数与语句数:每个类平均有 4.33 个方法,每个方法平均有 2.31 条语句 ,方法功能相对较为单一,符合良好的设计原则。
最复杂方法:NormalCargo.getRate()方法最为复杂,行数为 100,复杂度为 5 ,可能存在逻辑过于复杂的问题,可考虑进一步拆分优化。
块深度指标:最大块深度为 3 ,平均块深度 1.57 ,平均复杂度 1.16 ,说明代码嵌套层次不算太深,整体复杂度尚可。
类的识别与功能推测
Client类:包含id、name、phone、address等属性,可能用于表示客户信息,提供获取客户相关信息的方法。
ShippingManagementSystem类:看起来是系统核心类,包含众多属性如各种航班、货物相关信息,可能负责管理整个货运流程,包括航班、货物、客户信息的整合与业务逻辑处理。
Airflight类:有航班相关属性如flightNo、departure、destination等,用于管理航班信息,如航班的出发地、目的地、航班号等。
涉及货物的类:如AbstractCargo及其子类NormalCargo、SpecialCargo ,用于处理货物相关逻辑,包括货物的属性(如尺寸、重量)以及运费计算等功能。
Inventory类:可能用于管理库存相关信息,从类图看与货物类有联系,或许负责货物库存的增减、查询等操作。
类间关系分析
继承关系:NormalCargo和SpecialCargo继承自AbstractCargo ,说明它们具有AbstractCargo的共性,同时可能有各自特有的属性和方法,体现了面向对象的继承特性,有助于代码复用和功能扩展。
关联关系:各个类之间存在大量关联关系,比如ShippingManagementSystem与Client、Airflight、各种货物类等都有关联,表明系统通过这些类之间的协作来实现货运管理功能,不同类相互配合完成业务流程。
第二次迭代作业
类图:

表:

分析:代码结构与风格
分支语句占比 0.0% ,代码执行路径较直接,条件判断逻辑少。
方法调用语句 6 条,模块化程度一般。
注释行占比 6.9% ,有一定注释,但仍可增加以提高可读性。
类与方法指标
有 6 个类和接口,数量合理。
平均每个类 14.17 个方法,每个方法平均 1.64 条语句 ,方法功能较单一。
最复杂方法是ExpediteCargo.cal(推测是计算相关方法 ),位于第 9 行,复杂度 1 ,整体方法复杂度低。
最大块深度 3 ,平均块深度 1.48 ,平均复杂度 1.00 ,代码嵌套层次不深,结构较清晰。
分析与比较:
类图方面
上次情况:类图中类的职责和关系较为清晰,各核心类(如客户、货物、航班、订单等类)的属性和方法有明确体现,类间关系(继承、关联等)表达准确,能较好反映航空货运管理系统业务逻辑。
本次情况:类图整体结构延续了之前的设计思路,类的划分和职责界定基本一致。不过在细节上可能更加完善,比如对支付策略相关类的展示更清晰,对类间关系的表示或许更精准。相比上次,更能体现出策略模式(支付策略)和继承多态(客户、货物类型)在系统中的应用。
代码度量指标方面
对比项 第一次 第二次
文件行数 337 行 394 行
语句数 169 条 151 条
分支语句占比 4.7% 0.0%
方法调用语句数 33 条 6 条
注释行占比 0.0% 6.9%
类和接口数量 9 个 6 个
平均方法数 / 类 4.33 个 14.17 个
平均语句数 / 方法 2.31 条 1.64 条
最复杂方法 NormalCargo.getRate() ,行数 100,复杂度 5 ExpediteCargo.cal ,行数 9,复杂度 1
最大块深度 3 3
平均块深度 1.57 1.48
平均复杂度 1.16 1.00
问题和解决
在编程过程中,遇到诸多难题。类间关系复杂,订单类与客户、货物、航班等类耦合度过高,导致修改一处代码需连带调整多处,维护困难;输入数据校验逻辑分散在主程序各处,重复代码多,难以统一修改,影响开发效率;业务扩展时,如新增货物类型,常需修改原有代码,违背开闭原则,降低了系统稳定性;运费计算逻辑因涉及多因素,代码中条件判断层层嵌套,导致方法复杂度飙升,可读性变差;异常处理不统一,程序遭遇非法数据输入或业务逻辑错误时,直接抛出系统异常,没有提供友好提示,用户体验不佳 。
针对上述问题,通过绘制类图、引入策略模式和依赖抽象接口,有效降低类间耦合;创建InputValidator工具类,集中处理输入数据校验,减少重复代码;采用策略模式重构业务逻辑,使新增功能时无需修改原有代码,遵循开闭原则;将复杂的运费计算逻辑拆解为多个原子方法,提升代码可读性;自定义BusinessException异常体系,统一规范异常处理,增强用户体验。
心得
通过本次航空货运管理系统的开发,我收获颇丰。在面向对象设计原则的应用方面,我深刻体会到了单一职责原则的重要性。将不同的功能模块拆分到独立的类中,如客户类负责客户信息管理和折扣计算,货物类专注于货物的计费逻辑等,使得每个类的功能明确,代码的可读性和可维护性大大提高。
里氏代换原则让我认识到子类与父类之间的正确关系。在客户类的设计中,个人客户和集团客户子类能够无缝替换父类,并且各自实现不同的折扣策略,既保证了代码的一致性,又实现了差异化的功能。
开闭原则指导我在设计代码时为未来的扩展预留空间。当需要新增客户类型、货物类型或支付方式时,只需创建新的类去实现相应的接口或继承相关抽象类,而无需修改原有的核心代码,这极大地增强了系统的可扩展性。
合成复用原则提醒我优先使用组合和聚合关系来实现代码复用,而不是过度依赖继承。在订单类中,通过聚合客户、航班、货物和支付策略等类的实例,实现了订单业务逻辑的整合,使得各个类之间的职责更加清晰,也方便了后续的功能扩展和维护。
依赖倒转原则让我明白高层模块不应该依赖底层模块,二者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。在整个系统中,通过接口和抽象类来定义规范,具体的实现类依赖这些抽象,使得系统的结构更加稳定,也更容易进行单元测试和功能替换。
然而,在开发过程中我也意识到还有很多不足之处。比如在代码的性能优化方面,没有充分考虑到大量数据处理时的效率问题;在错误处理机制上还不够完善,对于一些异常情况的处理不够灵活和全面。未来,我将继续深入学习和实践这些设计原则,不断优化代码,提高自己的软件开发能力。

posted @ 2025-05-25 20:38  森喜刚  阅读(15)  评论(0)    收藏  举报