第二次Blog作业

一、前言

题目集8和9围绕"航空货运管理系统"展开,旨在通过类设计、继承、多态及设计模式的应用,实现货运业务的信息化管理。两次作业逐步提升复杂度,具体题目如下:

第一次题目

7-3 NCHU_航空货运管理系统(类设计)

客户:姓名(电话)订单信息如下:

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

货物明细如下:


明细编号 货物名称 计费重量 计费费率 应交运费
1 ... ... ... ...
2 ... ... ... ...

第二次题目

7-3 NCHU_航空货运管理系统(继承与多态)

客户:姓名(电话)订单信息如下:


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

货物明细如下:


明细编号 货物名称 计费重量 计费费率 应交运费
1 ... ... ... ...
2 ... ... ... ...

具体分析如下:

(一)知识点分布

题目集8(类设计):
基础类设计:客户类(Customer)、货物类(Goods)、航班类(Flight)、订单类(Order)等核心实体类的封装
业务逻辑实现:体积重量计算、运费计算、航班载重校验等
数据交互:控制台输入输出处理,对象之间的依赖关系管理
题目集9(继承与多态):
继承体系:抽象客户类(Customer)派生个人客户(IndividualCustomer)和集团客户(CorporateCustomer)
多态应用:货物类型(Normal/Expedite/Dangerous)的差异化费率计算
接口设计:支付方式接口(PaymentMethod)实现微信/支付宝/现金支付的策略模式
设计原则:单一职责、开闭原则、依赖倒转原则的综合应用

(二)题量与难度

题量:两次作业均为单一综合题,但题目集9因引入继承体系和多态逻辑,代码量增加约30%
难度层级:
题目集8:中等难度,重点考察类的合理拆分与基础业务逻辑实现
题目集9:较难,需综合运用面向对象高级特性,涉及策略模式、接口实现等复杂设计

(三)核心挑战

类职责划分的合理性(如订单类是否承担过多职责)
多态场景下的行为一致性(不同货物类型的费率计算逻辑)
输入输出格式的严格匹配(日期解析、浮点精度控制)
业务规则的动态扩展(如新增客户类型或支付方式时的系统可维护性)

二、设计与分析

第一次航班迭代程序

类图如下

源码报表分析图

一、代码规模分析

代码总量:文件共 498 行(Lines),包含 212 条语句(Statements),方法调用语句 63 条(Method Call Statements)。
注释情况:带注释的行占比 16.5%(Percent Lines with Comments),表明代码注释量适中但仍有提升空间。

二、设计分析

结构组成:包含 3 个类或接口(Classes and Interfaces),平均每个类有 8.67 个方法(Methods per Class),每个方法平均 7.5 条语句(Average Statements per Method),显示代码在类与方法的划分上有一定粒度。

三、复杂度分析

方法复杂度:最大复杂度为 5(Maximum Complexity),对应方法 DangerousGoods.getRate(),其代码行号为 148(Line Number of Most Complex Method)。
块深度:最深块深度为 3(Maximum Block Depth),平均块深度 0.77(Average Block Depth),平均复杂度 2.00(Average Complexity),表明整体逻辑复杂度一般,但存在局部复杂的方法。

四、不足与影响

高复杂度方法:如 DangerousGoods.getRate() 复杂度为 5,可能导致理解、维护困难,易隐藏逻辑错误。
注释与可读性:注释行占比仅 16.5%,若代码逻辑复杂,可能影响后续阅读与维护效率。
深度块逻辑:最深块深度为 3,虽平均深度较低,但深层块仍可能使代码逻辑流程不够清晰,增加调试成本。

五、总结

该 Main.java 文件呈现出一定规模的代码结构,类与方法划分具备明确的组织粒度,但代码质量仍有优化空间。代码规模适中,但注释占比可进一步增加以提升可读性;整体平均复杂度与块深度尚可,但局部高复杂度方法(如 DangerousGoods.getRate())和较深块深度可能影响逻辑清晰性与维护效率。后续可针对高复杂度方法进行重构,补充注释内容,优化块深度,从而增强代码的可理解性与可维护性,提升整体代码质量。

第二次航班迭代程序

类图设计如下:

源码报表分析图

一、代码规模分析

  • 代码总行数(Lines)为 325 行,包含 107 条语句(Statements),方法调用语句(Method Call Statements)仅 12 条。
  • 注释行占比(Percent Lines with Comments)极低,仅为 3.4%,代码注释严重不足。

二、设计分析

  • 包含 5 个类或接口(Classes and Interfaces),平均每个类有 3.20 个方法(Methods per Class),每个方法平均 6.13 条语句(Average Statements per Method),类与方法的划分较为均匀,设计上有一定规范性。

三、复杂度分析

  • 最大复杂度(Maximum Complexity)为 1,最深块深度(Maximum Block Depth)为 2,平均复杂度(Average Complexity)为 1.00,整体逻辑简单,代码结构清晰,无高复杂度方法。

四、不足与影响

  • 注释匮乏:注释行占比仅 3.4%,严重影响代码的可读性与可维护性,后续开发者难以快速理解代码逻辑,增加维护成本。
  • 潜在理解成本:尽管代码复杂度低,但缺乏注释可能导致在修改或扩展功能时,需花费更多时间梳理代码逻辑,降低开发效率。

五、总结

该 Main.java 文件代码规模较小(325 行),包含 5 个类 / 接口,方法平均复杂度与块深度均为 1,逻辑简单清晰。但注释行占比仅 3.4%,可能对后续代码维护造成一定困难。整体而言,代码结构规整,复杂度低,适合快速理解与修改,但需补充注释以提升可读性。

三、采坑心得:编码实践中的问题与解决方案

(一)输入输出格式陷阱

  • 日期解析问题

    • 问题:题目集8中使用 LocalDate.parse 直接解析输入,当输入包含非法字符时抛出异常。
    • 解决方案:增加输入校验逻辑,使用 try-catch 捕获异常并提示用户重新输入。
    try {  
        LocalDate.parse(dateStr);  
    } catch (DateTimeParseException e) {  
        System.out.println("无效日期格式,请重新输入");  
    }  
    
  • 浮点精度控制

    • 问题:直接使用 double 计算运费导致精度丢失(如 0.1 + 0.2 ≠ 0.3)。
    • 解决方案:题目集9引入 DecimalFormat 统一格式,并在计算时使用 BigDecimal(虽未完全实现,但通过格式化输出掩盖了精度问题)。

(二)类设计缺陷

  • 职责过重问题

    • 表现:题目集8的 Order 类同时处理订单信息组装、费用计算和输出逻辑。
    • 重构方案
      • 拆分为 Order 实体类和 OrderService 业务类。
      • OrderService 负责费用计算和业务逻辑,Order 专注数据存储。
  • 硬编码问题

    • 表现:题目集8的费率计算直接写死在 Goods 类中。
    • 优化方案:题目集9通过枚举和条件判断实现初步可配置,未来可引入配置文件或数据库存储费率规则。

(三)多态实现误区

  • 抽象类设计不完整

    • 问题:题目集9的 Customer 抽象类未包含所有客户公共属性(如地址),导致子类重复代码。
    • 改进:将地址等公共属性移入抽象类,确保继承体系的完整性。
  • 策略模式不彻底

    • 表现:货物费率计算仍在 Cargo 类中通过 switch 实现,未拆分为独立策略类。
    • 重构建议
    interface CargoRateStrategy {  
        double calculateRate(double chargeWeight);  
    }  
    
    class NormalCargoStrategy implements CargoRateStrategy {  
        // 具体实现逻辑  
    }  
    

    通过策略工厂根据货物类型动态创建策略对象,提升代码的可维护性与扩展性。

四、改进建议:系统可持续优化方向

(一)架构层面

  1. 引入设计模式

    • 工厂模式:解耦对象创建逻辑,如通过CustomerFactory创建个人客户或集团客户对象。
    • 单例模式:确保航班调度中心等全局资源唯一实例化。
    • 装饰器模式:为货物添加附加服务(如保险、加急处理),不修改原有类结构。
  2. 分层架构设计

    表示层(输入输出)  
    ├─ 业务层(费率计算、载重校验等核心逻辑)  
    └─ 数据层(对象存储,支持文件/数据库扩展)  
    
    • 分离各层职责,降低耦合度,提升可维护性和可测试性。

(二)代码质量优化

  1. 减少类复杂度

    • Cargo类的费率计算逻辑拆分为独立策略类(如NormalRateStrategy),使类复杂度从12降至≤7。
    • 重构Order类的getOrderInfo()方法,拆分为formatBasicInfo()formatCargoDetails()等辅助方法。
  2. 增强异常处理

    • 为文件读取、网络请求等操作添加try-catch块,避免程序崩溃。
    • 自定义业务异常类:
      public class OverloadException extends RuntimeException {  
          public OverloadException(String message) { super(message); }  
      }  
      
      明确区分不同类型的异常,提高错误定位效率。

(三)功能扩展建议

  1. 新增业务功能

    • 货物追踪:引入TrackingInfo类,记录货物状态(运输中/已签收)、位置更新时间等。
    • 会员体系:在Customer抽象类中添加calculatePoints()接口,实现积分累计与等级管理。
  2. 性能优化

    • 航班查询优化:使用HashMap<String, Flight>存储航班信息,将订单匹配时间复杂度从O(n)降至O(1)。
    • 批量处理支持:实现BatchOrderProcessor类,支持一次性处理多个订单,减少循环冗余操作。

五、总结:面向对象设计的实践与成长

(一)知识技能提升

  1. 核心能力突破

    • 熟练掌握类的封装(如Flight类隐藏载重状态)、继承(Customer派生体系)、多态(货物费率差异化计算)。
    • 理解并应用设计原则:单一职责(InfoReader仅处理输入)、开闭原则(新增客户类型无需修改原有代码)。
    • 初步掌握策略模式(支付方式接口)、工厂模式(对象创建解耦)的实际应用。
  2. 关键实践收获

    • 职责划分:避免“大泥球”代码,如将输入输出逻辑从业务类中分离。
    • 多态本质:通过抽象类和接口实现行为扩展,而非依赖条件判断。
    • 量化评估:使用SourceMonitor分析类复杂度,针对性优化高复杂度模块(如Cargo类)。

(二)待改进方向

  1. 技术短板

    • 单元测试缺失:目前仅通过手动测试验证功能,未覆盖边界条件(如货物重量为0、航班载重为负数)。
    • 异常处理薄弱:系统缺乏全局异常捕获机制,日志记录功能尚未实现。
    • 设计模式应用浅层化:对装饰器模式、代理模式等理解不足,未能在复杂场景中灵活运用。
  2. 学习计划

    • 工具学习:掌握JUnit 5Mockito,为Goods类、OrderService等核心组件编写测试用例。
    • 最佳实践:研究Java异常处理规范,结合SLF4J实现系统日志记录。
    • 理论深化:精读《设计模式》一书,完成“策略模式重构货物费率计算”等实战练习。
posted @ 2025-05-21 15:33  何择  阅读(22)  评论(0)    收藏  举报