第二次blog作业

一、前言
这次8、9两个题目集共有6道编程题,主要考察我们对于继承的运用,相比较于上次的电梯调度程序问题,这次的航空货运运费计算程序不对算法做过多考察,更加侧重于培养对实际问题的理解和对类的设计,迭代的层层递进,对代码的结构严谨、功能的完善和类的合理性有更高要求的考察,并要符合六个基本原则:
1.单一职责原则
2.里氏代换原则
3.依赖倒转原则
4.迪米特原则
5.合成复用原则
6.开闭原则
这六个原则规范我们去设计类,使类之间的关系更加清晰明确,耦合度更低,便对代码的进一步修改,为日后的Java学习培养设计良好的习惯。

二、设计与分析
题目集8:
前两道题都集中于对已经做过的题目进行重构,在原先的基础上添加继承与多态,帮我们巩固了先前所学的继承方法的运用,第三道题未考察继承,主要考察类的设计,第一次航班货运编程题需要我们将题目拆分,并规划出几个类完成题目要求,而本次blog主要集中于第三道题目:
航空货运管理系统(类的设计)
一、计费重量的确定
某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包
括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。这个题目主要考虑货物重量/体积。
二、基础运费计算
空运以实际重量(Gross Weight)和体积重量(Volume Weight)中的较高者作为计费重量。
费率的计算方法如下:

基础运费 = 计费重量 × 费率
三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
客户信息(姓名,电话号码等)
货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选航班号,订单日期)
支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独计费
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信息报表及货物明细报表
本次题目重点考核面向对象设计原则中的单一职责原则、里氏代换原则、开闭原则以及合成复用原则

以下为编写的代码的PowerDesigner类图

由类图可知将代码分为了四个类,分别为customer顾客、flight航班、cargo货物、order订单,类的数量太少,并且类与类之间的耦合度较高,在第二次航运货物编程题里会进一步改善

代码生成的SourceMonitor报表

可以看出这段代码可读性和维护性较差,核心逻辑过于集中在几个高复杂度的方法里,比如 Main.main()和Cargo.getShippingFee(),导致代码臃肿且难以修改。此外,代码里没有注释,当他人阅读时会很头疼。同时嵌套层次较深,部分代码块深度达到3,增加了理解难度。虽然类的数量合理,但某些方法,比如 Order.printOrder(),调用了太多外部方法,耦合度较高。总的来说,代码能够满足题目的需求,并且通过测试点,但代码结构不够清晰,不利于后面的调整与修改。

题目集9:
题目集9里新增了魔方的表面积和体积的计算编程题,也是主要考察我们对继承与多态的运用。另一道点线面问题则是进一步迭代,在原先代码的基础上,增加一个容器类,利用ArrayList来实现对点线面的增删改,这里我们具体分析航空货运管理系统的编程题。
航空货运管理系统(继承与多态)
在题目集8的代码基础上进行修改,费率和基础运费的计算更改

基础运费 = 计费重量 × 费率 × 折扣率
折扣率是指不同的用户类型针对每个订单的运费可以享受相应的折扣,
在本题中,用户分为个人用户和集团用户,其中个人用户可享受订单运费的 9折优惠,集团用户可享受订单运费的 8 折优惠
题目说明上也有变化
支付方式里新增现金支付,并且本题需要新增用户、支付方式、货物三个类,并继承处理
本次题目重点考核面向对象设计原则中的单一职责原则、里氏代换原则、开闭原则以及合成复用原则、依赖倒转原则
本次代码类图如下

由于需要划分出来的类较多,截图需要所以较密集,按照题目要求,client类派生出individual和corporate两个子类,payment类派生出wechat、alipay、cash三个子类,goods类派生出urgent、dangerous、normal三个子类,相比较题目集8里的类图,新增加了agent中间处理类或容器类,用来处理输出,计算运费等功能,每个类都有各自的职能,满足SRP原则
SourceMonitor生成报表图如下:

这段代码的结构有一定的模块化设计,比如将不同货物类型Dangerous、Normal、Urgent的费率计算逻辑拆分到各自的类中,符合单一职责原则。然而,主要问题集中在Main.main()方法上,它的复杂度高达13,包含61行代码和14个方法调用,这使得核心逻辑过于臃肿,难以维护。此外,Agent.print()和多个rateCalculate()方法也存在高复杂度和较深的嵌套层次,最大块深度达到4,增加了代码的理解难度。最明显的问题是代码中没有注释(0%注释率),这对后续的维护和协作开发非常不利,渐渐地也会为以后的java设计开发培养不好的习惯。虽然类的数量增加到9个,但平均每个类只有2.67个方法,部分类的功能划分可能过于零散,而Agent类又承担了过多职责。这些问题应该在后续的题目练习中逐渐改善并解决。
三、踩坑心得
1.对于我来说,在首先看到这种输入格式这么长一段的题目(输入格式如图),我的第一反应就是逃避,不想动脑去想这种题目类该如何划分最合理,其实这种心态是非常不可取的,应该看到这种题目后,一步一步慢慢把题目啃下来,不会为后面写题带来太多压力

2.我是看到题目后就直接在IDEA里编写了,这样给了刚开始打代码的我很大的压力,导致我写题断断续续,写了会就去玩了,效率很低下,后面打代码的时间很长,总是打了写,写了犹豫一会,然后又删了,总在纠结这里类的方法的设计合不合理,一个类不能单独拿出来想怎么打,得结合题目的意思来规划代码,就很浪费时间,我一度都不太想继续写这道题
心得
在打代码之前就把类图设计个大概的样子出来,不需要太详细,但至少应该有几个类、类与类之间的关系是怎样等等,为后面打代码节约一大笔时间,后续边打代码边往类里填充方法。
3.我在航空货运系统的编程题里,有几个测试点一直过不去,50分的满分只能拿到12分,测试了样例后,我发现结果和预期结果没有差别,我很疑惑为什么,后来过了一个小时左右,我找到了
问题的根本所在:
计算货物总质量时,是各个货物的计费重量相加,而不是直接把实际重量相加。
后来我查看了排名里的具体内容,十几位同学和我一样这道题都只有12分,我猜测他们可能也都是因为这个问题,所有我认为这一个较为普遍且有借鉴意义的踩坑心得。

4.输出格式上,在第一次航空货运管理系统的编程题里,我一直因为格式错误过不去测试点,后来运行了测试用例,对比了预期结果和实际结果,我才发现是图中所对应的空格里要用\t而不是直接用空格隔开。

四、改进建议
1.打代码时多加点注释,提升代码的可读性,以后加入到团队项目里,这一点能为团队队员减少很多不便。
2.拆分长方法,将例如第一次航空货运管理系统的main()和getShippingFee()拆分为更小的单一职责方法。
3.减少嵌套,题目集9里航空货运管理系统里的嵌套层次高达4,不利于后期维护。
4.降低代码的复杂度,对高复杂度的方法进行拆分。
5.打这种迭代的编程题前,先画个大致的类图。
6.下次希望自己遇到这种迭代量大的题目第一反应不是逃避,而是静下心慢慢把题目啃下来。
五、总结
对于本阶段两次题目集的题目,我学到在实战里更加熟练运用继承,并且在信息量较大的题目里划分类更加成熟,并且符合上述的六个一本原则,并且学会了容器类的应用,arraylist的具体用法。我相信在一次又一次的题目集的锻炼下,我的代码能力、逻辑思维能力等都在逐步提高,相较于刚开学时,我对Java这门语言的运用也上升了好几个level,虽然我现在还没有那么厉害,但在慢慢的学习这种能力也会提升。同时,希望下个学期课题组挑选教材时,能选择一本实例更多的教材,这本Java教材里的程序较少,对我个人的能力而言,我更偏向于从实例里学懂一些Java的一些具体运用,如string类的数据该怎么从键盘里读取。另外,我觉得各位老师都很认真严谨负责,为我们的Java学习提供了很多保障,希望在剩下的课程里,能继续学习,增强自己的java语言能力。

posted @ 2025-05-25 21:48  wu345  阅读(17)  评论(0)    收藏  举报