题目集 8~9 总结性博客
题目集 8~9 分析
前言:题目集 8 和 9 围绕面向对象设计,涵盖抽象类、继承、多态及策略模式等知识,共 6 题。前者侧重基础(如几何图形多态、简单货运计费),难度中等;后者深化设计模式(如支付策略解耦)和复杂业务(多类型客户 / 货物规则),难度较高,通过阶梯式场景推动从基础编码到系统设计的能力提升。
题目集8分析
-
几何图形绘制(Line/Point/Plane 类)
• 知识点:
o 抽象类Element的使用(强制子类实现display()方法)。
o 类的封装(如Line类包含Point对象、颜色属性)。
o 多态性(通过Element父类引用调用子类对象的display()方法)。
• 设计要点:
o Point类实现坐标显示,Line类计算线段长度并展示端点信息,Plane类仅显示颜色,体现不同图形的差异化逻辑。
o 输入校验:主程序检查坐标值是否在有效范围(0 < x/y ≤ 200),避免无效数据。
• 采坑心得:
o Point类中dispaly()方法拼写错误(应为display()),导致子类未正确重写父类方法。
o 线段长度计算时未考虑浮点数精度问题,需通过String.format("%.2f", ...)格式化输出。 -
机械控制杆模拟(Lever/Dial/Agent 类)
• 知识点:
o 类的组合(Agent类包含Lever、Dial、Brush对象)。
o 状态管理(控制杆档位、刻度盘刻度的状态变化)。
o 策略模式雏形(通过tableType区分不同表格的计算逻辑)。
• 设计要点:
o Lever和Dial类通过leverUp()/leverDown()等方法实现状态变更,Agent类根据档位和刻度计算刷子速度。
o 输入循环处理:通过while (op != 0)持续读取操作指令,直至输入 0 结束。
• 常见问题:
o 表格类型(tableType)的校验不完整,未处理非 1/2 的输入值,需在开头添加if (tableType < 1 || tableType > 2)的判断。
o Brush类的speed初始值为 0,但未在Agent.dealSpeed()中处理档位为 “停止” 时的速度重置。 -
航空货运管理系统
• 知识点:
o 业务类设计(客户、货物、航班、订单信息类)。
o 计费逻辑(体积重量与实际重量取较大值,费率根据重量区间计算)。
o 数据聚合(InformationForm类整合各类信息并展示)。
• 设计要点:
o 业务类设计
1.客户类(CustomerInformation):封装了客户的基本信息,如ID、name、telephoneNumber、address,通过属性的 getter 和 setter 方法实现对客户信息的访问和修改,是整个业务中客户相关操作的基础数据载体。
2.货物类(ItemInformation):包含货物的标识、尺寸、重量等属性,同时通过billingWeight()和calculatePrice()等方法实现了货物计费的核心逻辑。其中billingWeight()方法根据体积重量与实际重量取较大值的规则计算计费重量,calculatePrice()方法结合费率计算货物的应交运费,体现了业务中货物计费的关键处理。
3.航班类(FlightInformation):记录航班的编号、起降机场、到达时间和最大载重等信息,通过isBiggerThanCapacity()方法校验货物总重量是否超过航班载重,是业务中保障运输可行性的重要环节。
4.订单类(OrderInformation):存储订单的编号、日期、收发件人信息等,是订单相关信息的存储和管理单元,在业务流程中起到整合订单相关数据的作用。
o 计费逻辑
1.计费重量计算:在ItemInformation类的billingWeight()方法中,通过公式double GrossWeight = length * height * width / 6000;计算体积重量,然后与实际重量比较,取较大值作为计费重量,这种方式符合实际物流计费中考虑体积和实际重量的规则。
2.费率计算:同样在ItemInformation类的chooseRate()方法中,依据货物重量区间(如weight > 0 && weight < 20、weight >= 20 && weight < 50等)来确定不同的费率,不同重量区间对应不同的费率标准,如rate1 - rate4 ,最后在calculatePrice()方法中,将计费重量与费率相乘得到货物应交运费,完整实现了货物的计费逻辑。
o 数据聚合
InformationForm类通过聚合CustomerInformation、ItemInformation、FlightInformation和OrderInformation类的对象,整合了客户、货物、航班和订单的各类信息。在show()方法中,将这些信息按照一定格式进行展示,包括客户信息、航班号、订单号、订单日期、收发件人信息、订单总重量、支付金额以及货物明细等,为用户提供了一个完整的业务信息呈现,方便用户了解订单的整体情况。
o
• 分析源码:
![]()
![]()
![]()
-
类与方法层面:类的方法数较多,可进一步拆分职责,提高内聚性。例如ItemInformation类中,计费相关方法可考虑提取到单独的计费策略类中。
-
注释补充:由于含注释代码行占比低,在关键方法(如billingWeight、chooseRate等)和业务逻辑处添加注释,解释代码意图和实现思路。
-
继承关系优化:ItemInformation继承自Pay,但继承关系使用较简单,可审视是否能通过接口或组合方式替代,使代码结构更灵活,遵循设计原则。
-
错误处理与输入校验:代码中对用户输入校验不足,如未检查输入合法性,应在获取用户输入处添加校验逻辑,避免非法输入导致程序异常。
• 采坑心得:
o 在代码中,Pay抽象类定义了四个费率常量(rate1-rate4),但这些常量被声明为private(默认访问权限)。而ItemInformation类继承自Pay类,在ItemInformation的chooseRate()方法中尝试直接访问这些费率常量时,由于访问权限限制,导致编译错误。这是因为子类无法直接访问父类的私有成员。解决方案:将Pay类中的费率常量的访问权限修改为protected或public,这样子类ItemInformation就可以正常访问这些常量。
o InformationForm类的show()方法直接包含了大量的控制台输出代码,将订单信息的展示逻辑与业务数据的处理逻辑紧密耦合在一起。这种设计使得代码的可维护性和可扩展性较差,例如如果需要将输出方式从控制台改为 Web 界面或其他形式,就需要修改show()方法的实现,违反了单一职责原则和开闭原则。解决方案:引入独立的展示层,将信息展示的职责分离出来。可以创建专门的视图类(如OrderView)来负责订单信息的展示,InformationForm类专注于业务数据的处理和管理。
题目集 9 分析
-
魔方表面积与体积计算(Solid/RubikCube 子类)
• 知识点:
o 抽象类与继承(Solid为几何体基类,Cube/RegularPyramid为具体形状)。
o 多态性(RubikCube子类重写getArea()和getVolume()方法)。
o 尺寸缩放(通过layer参数放大基础几何体的边长)。
• 设计要点:
o SquareCube(立方体魔方)和RegularPyramidCube(正棱锥魔方)根据层数计算放大后的边长,再调用基类的表面积和体积公式。
o 输出格式化:使用printf("%.2f")控制结果精度。
• 采坑心得:
o 正棱锥的表面积和体积公式可能存在数学错误(如正三棱锥与正四棱锥的公式混淆),需验证几何公式的正确性。
o RubikCube抽象类未强制子类实现getArea()和getVolume(),导致子类漏写方法时编译器不报错。 -
几何图形容器(Element/Line/Plane + GeometryObject)
• 知识点:
o 集合类使用(ArrayList存储图形对象)。
o 增删改查操作(通过菜单选项添加 / 删除图形元素)。
o 多态遍历(通过for-each循环调用display()方法)。
• 设计要点:
o GeometryObject类封装集合操作,主程序通过输入指令(1-4)控制元素的增删,0 退出后遍历展示所有元素。
o 输入索引时需转换为数组下标(如输入 1 对应索引 0),避免越界异常。
• 常见问题:
o 删除操作未校验索引有效性(如输入负数或超过集合大小的索引),需添加if (index >= 1 && index <= size)的判断。
o Line类的getDistance()方法参数名与类属性名重复(如Point point1与类中的point1),可改为p1/p2提高可读性。
3-4. 航空货运管理系统
• 知识点:
o 抽象类与子类继承(Customer/Item抽象类,IndividualCustomer/DangerousItem等子类)。
o 策略模式(PaymentStrategy接口实现支付方式解耦)。
o 复杂业务逻辑(客户折扣、货物类型差异化费率、支付方式动态切换)。
• 设计要点:
o 客户模块: Customer抽象类作为客户的基类,定义了客户的基本属性(如id、name等)和抽象方法(getType()、getDiscountRate())。IndividualCustomer和CorporateCustomer子类继承Customer,并分别实现getDiscountRate()方法,返回个人用户和企业用户对应的折扣率。通过Customer抽象类的getDiscountRate()方法,区分个人用户(折扣率 0.9)和企业用户(折扣率 0.8)。在计算订单总费用时,根据客户类型应用不同的折扣率,体现了业务逻辑的差异化处理。
o 货物模块:Item抽象类定义了货物的基本属性(如id、name等)、抽象方法(getType()、getRate())以及通用方法(如getBillingWeight()、calculatePrice())。不同的货物子类(NormalItem、DangerousItem、ExpediteItem)继承Item,并根据货物类型实现不同的getRate()方法,以计算各自的计费费率。支付模块:Order类持有PaymentStrategy对象,通过getPaymentMethod()动态获取支付方式。Item抽象类定义了getRate()方法,不同的货物子类(普通、危险、加急)根据货物重量实现不同的费率计算规则。这使得在计算货物运费时,能够根据货物的实际类型应用合适的费率,实现了业务逻辑的精细化处理。
o 支付模块:PaymentStrategy接口定义了获取支付方式的方法getPaymentMethod(),具体的支付策略类(AlipayStrategy、WechatPayStrategy、CashStrategy)实现该接口。Order类持有PaymentStrategy对象,在创建订单时可以根据用户输入动态设置支付策略,并在展示订单信息时调用getPaymentMethod()获取支付方式名称。Order类通过持有PaymentStrategy对象,在运行时可以根据用户输入动态设置支付方式,通过调用getPaymentMethod()获取具体的支付方式名称,实现了支付方式的灵活切换。
• 复杂度分析:
![]()
![]()
![]()
-
类与方法层面:虽然平均复杂度低,但每个类方法数较多(14.33 个),可以审视能否进一步拆分职责,让类和方法更加单一职责化,提高代码的内聚性和可维护性。例如,对于Customer、Item相关的类,某些通用功能或属性操作方法可以考虑提取到工具类中。
-
注释补充:鉴于含注释的代码行百分比仅 2.5% ,在关键方法(如计算费用、载重校验等方法)以及复杂业务逻辑处添加注释,解释代码的意图和实现思路,方便他人和自己后续维护。
-
代码结构优化:虽然最大块深度和复杂度指标较好,但仍可进一步检查代码中是否存在可以简化的嵌套逻辑或重复代码,持续优化代码结构。
• 踩坑心得:
o 货物类型输入校验不足(如未处理非法类型字符串),需在createItem()方法中添加容错逻辑。
o 在计算订单总费用时,虽然代码中使用了sum * discountRate来应用客户折扣,但没有明确在所有货物计费后执行该计算。如果在计算货物费用的过程中存在其他逻辑干扰,或者没有确保所有货物都已经计算完费用再应用折扣,可能会导致总费用计算错误。解决方案:通过编写单元测试来验证总费用计算的正确性。可以创建不同类型客户(个人和企业)的订单,并添加不同类型和数量的货物,然后验证总费用是否按照正确的折扣率计算。同时,在代码中明确总费用计算的时机,确保在所有货物费用计算完成后再应用客户折扣。
o 在判断航班是否能承载订单货物时,原代码中使用了错误的方法来获取货物重量总和,应该使用getTotalWeight()(计费重量总和),而不是totalWeightNumber()(实际重量总和)。这样会导致载重校验不准确,可能会出现航班超载但程序判断可以承载的情况。解决方案:在判断航班载重时,将获取货物重量总和的方法修改为调用informationForm.getTotalWeight(),确保使用的是计费重量总和进行载重校验,以保证航班载重校验逻辑的正确性
学习收获:通过题目集 8-9 的实践,深入掌握了面向对象设计的核心思想,包括抽象类与多态的应用、类的组合关系及策略模式等设计模式,能对几何图形系统、设备控制逻辑及航空货运管理系统进行分层建模与业务规则实现。但在代码可维护性(魔法值处理、长方法拆分)、异常处理完善性及设计模式应用深度(如模板方法、动态工厂)等方面仍有不足,未来需进一步学习高级设计模式、强化代码重构能力与测试覆盖,以提升系统的健壮性与扩展性。







浙公网安备 33010602011771号