一、前言

对这两次题目集的总结:

这两次题目集相较于上次迭代作业来说,在题目量和难度上都做了下调。但要求我们在理解题目意思、设计好程序结构、掌握并运用知识这三方面有一定的要求。涉及到类的继承与多态,抽象类的设计和抽象方法的灵活运用。以及面向对象的几种程序设计的原则(单一职责原则、里氏代换原则、开闭原则、合成复用原则)。锻炼我们面向接口编程的能力。需要我们不断规范自己的类设计、优化代码结构、降低代码的耦合性,提高程序的可扩展性。

二、设计与分析

因为题目集的前面几题都比较基础,所以该部分重点对航空货物管理系统迭代题做分析。

第一次电梯题目的设计与分析

题目要求:编程实现一个航空货物管理系统,对于订单信息的一些基本数据的输入(客户信息,收件人、发件人、货物信息、航班信息、支付方式等)。还有空运货物的重量计算,以及按照不同的重量区间具有不同的费率。最后一订单表的形式输出。并且本次题目重点考核面向对象设计原则中的单一职责原则、里氏代换原则、开闭原则以及合成复用原则。

类图设计:

考虑到此次的题目是按照面向对象设计原则来进行打分的,所以类设计的比较多。

类的总体设计

  • Main类: 正确的将数据储存并且由这些数据构建具体实现类,并且能处理货物是否超载的逻辑判断。
  • People类: 作为一个抽象的父类,里面有用户的名字,电话号码,地址的信息,以及Getter、Setter抽象的展示信息方法。
  • Sender类: 该类继承与People类作为一个具体实现类,继承了父类的属性并且实现了父类当中的展示信息方法。
  • Recipient类: 该类继承与People类作为一个具体实现类,继承了父类的属性并且实现了父类当中的展示信息方法。
  • Customer类: 该类继承与People类作为一个具体实现类,继承了父类的属性,同时还有自己的特有的编号属性并且实现了父类当中的展示信息方法。
  • Flight类: 属性有航班的基本信息如始发地、终点和航班的编号。然后有按格式展示航班的基本信息的方法。
  • Freight类: 这个类主要就是用来表示航空货物的一些信息,同时里面还有计算并获取用于计算货物真实重量的方法,并且与下面的货物链表类相关联。
  • FreightList类: 作为货物的容器,主要就是用来计算货物的总重量,以及用于支付类的计算金额。
  • PayMethod接口 主要就是做一个接口来放支付方式的抽象方法,用来展示支付方式。提高代码的可扩展性。
  • RateStrategy接口 接口来放不同费率计算方式的抽象方法,用来确定用哪种费率计算方式。提高代码的可扩展性。
  • PayMent类 组合货物链表和支付方式和费率策略类,用于计算支付订单所需要的总金额,并具有按订单的形式的输出的方法。
  • Order类 具有订单的编号和日期,同样也有按订单信息形式输出的方法。
  • ShowOrder类 组合上面有按订单行动展示自身信息的类,主要控制订单格式的输出的顺序逻辑。



    Source Monitor分析结果:

点此处看方法具体复杂度

分析与心得

 由上面的Source Monitor分析的结果来看不难发现,这次题目集提交的代码虽然类的设计有很多,但是依旧有不合理的地方,还是有可以改进的地方。

  • 类的职责不够单一 有些具体信息类有展示的方法,并没有完全的做到类的单一职责,应该将这种展示信息的方法分离出来,降低耦合度,提高系统的可扩展性。
  • 代码注释量过少,可读性差:代码的注释量依旧没有达到规范的范围。说明当时在完成这个题目集的时候没有考虑到以后代码还需要不断地改进和维护。

    心得:通过深刻剖析第一次的代码,以及使用特定工具来检查代码不难发现这次的代码在设计合理的类间关系、优化代码结构和增强代码的可读性上面还有很大的改进和提升的空间。

第二次电梯题目的设计与分析

题目要求: 相较于上一次新增了不同的客户类型,不同的货物,不同的支付方式。具体如下折扣率是指不同的用户类型针对每个订单的运费可以享受相应的折扣,在本题中,用户分为个人用户和集团用户,其中个人用户可享受订单运费的 9折优惠,集团用户可享受订单运费的 8折优惠。本次作业费率与货物类型有关,货物类型分为普通货物、危险货物和加急货物三种。支付方式(支付宝支付、微信支付、现金支付)

由于这次有不同的客户类型,不同的货物,不同的支付方式。所以我采用了接口的形式来应对这些不同的情况。

类图:

设计

将上一次的代码的类设计做出以下的改变,下面是设计的每个类的功能:

  • Main类: 正确的将数据储存并且由这些数据构建具体实现类,并且能处理货物是否超载的逻辑判断。然后新增按照不同的输入类型创建相对应的接口,能够应对此次题目新增的功能。
  • People类: 作为一个抽象的父类,里面有用户的名字,电话号码,地址的信息,以及Getter、Setter。将第一次题目集展示信息的方法剥离出去。
  • Sender类: 该类继承与People类作为一个具体实现类,继承了父类的属性。
  • Recipient类: 该类继承与People类作为一个具体实现类,继承了父类的属性。
  • Customer类: 该类继承与People类作为一个具体实现类,继承了父类的属性,同时还有自己的特有的编号属性。
  • Flight类: 属性有航班的基本信息如始发地、终点和航班的编号。
  • Freight类: 这个类主要就是用来表示航空货物的一些信息,同时里面还有计算并获取用于计算货物真实重量的方法,并且与下面的货物链表类相关联。
  • FreightList类: 作为货物的容器,主要就是用来计算货物的总重量,以及用于支付类的计算金额。
  • PayMethod接口 主要就是做一个接口来放支付方式的抽象方法,用来展示支付方式。提高代码的可扩展性。
  • RateStrategy接口 该接口来放不同费率计算方式的抽象方法,用来确定用哪种费率计算方式。提高代码的可扩展性。
  • DiscountStrategy接口 该接口来放不同客户类型的折扣计算方式的抽象方法,用来确定用哪种折扣计算方式。提高代码的可扩展性。
  • PayMent类 组合货物链表和支付方式和费率策略类,用于计算支付订单所需要的总金额。
  • Order类 对比上次题目的类该类具有订单的编号和日期,还组合了客户,收件人,发件人,航班信息。将这些信息的展示方式放在这个类当中来展示。做好类的单一职责(SPR)。
  • OrderDetais类 新增订单明细类,组合支付类,和货物链表类。主要就是用来展示一些有关于订单金额信息的类。进一步解耦,提高扩展性。
  • ShowOrder类 组合上面订单类和订单明细类,展示订单信息的类,主要控制订单格式的输出的顺序逻辑。

Source Monitor分析结果:

点此处看方法具体复杂度

分析与心得

 由上面的Source Monitor分析的结果来看,第二次提交的通过代码在新增了不同类型的处理情况后,代码行数从 ​​510 增至 ​​670​​,设计多个接口和做到展示信息的和订单信息职责拆分后新增OrderDetails类,符合接口编程的设计预期。质量明显要比第一次的好的多,但是还是存在一些问题的:

  • 代码的注释还是太少:注释量站的百分比下降,可能是因为在重新设计类后,代码行数的增多,导致第二次的逻辑部分即使增加了代码注释,注释的量依旧没有达到Java规范的量。
  • 代码的最大复杂度增加: 代码的最大复杂度比上次提高了,说明在某个方法的调用或者计算的方式依旧有可以提升的空间。

    心得:虽然这次的代码仍有两个方面没有达到要求的范围,但相比上次题目集已经有了很大的改进了,不过还是要养写代码注释的习惯,尤其是逻辑部分和调用方法部分。使代码逻辑容易理解和调试,符合Java编程原则规范了。

三、踩坑心得

本部分对每次题目集提交代码出现的问题和心得进行总结

  • 1.不能正确的构建具体类:在主方法里使用nextLine来解析输入的数据时,总是忘记把String类型的数据转换为对应的数据类型。还有就是传入的构造数据的顺序老是弄错。导致了不能正确的构建具体实现类,进而浪费了一些时间。

  • 2.无法获取父类的属性 在编写代码的时候,把父类的属性设置为了private的,然后又没设计get方法导致无法获取属性。

  • 3.超载信息提示的格式错误 第一次提交的时候回答详情里面超载信息的那部分显示格式错误,一开始我以为是航班号的信息有问题,浪费了一些时间在检查航班类的构建和信息输出上面。后面才发现,我是在main方法里面运用println输出超载信息的时候“”里面忘记加一个空格导致的格式错误。

四、改进建议

点击查看可改进的代码
    static public void main(String[]args){
Scanner sc = new Scanner(System.in); // 读取客户信息
String customerNumber = sc.nextLine();
String customerName = sc.nextLine();
String customerTel = sc.nextLine();
String customerAddress = sc.nextLine();
//创建客户
Customer customer = new Customer(customerNumber, customerName, customerAddress, customerTel); // 读取货物数量
int freightCount = Integer.parseInt(sc.nextLine());
FreightList freightList = new FreightList(); // 读取每个货物信息
for (int i = 0; i < freightCount; i++) {
Freight freight = new Freight(
sc.nextLine(),//number
sc.nextLine(), // name
Double.parseDouble( sc.nextLine()), // width
Double.parseDouble( sc.nextLine()), // length
Double.parseDouble( sc.nextLine()), // height
Double.parseDouble( sc.nextLine())//weight
);
freightList.addFreight(freight);
} // 读取航班信息
Flight flight = new Flight(
sc.nextLine(), // flightNumber
sc.nextLine(), // departure
sc.nextLine(), // arrival
sc.nextLine(), // date
Double.parseDouble(sc.nextLine()) // maxcapacity
); //判断重量是否满足该航班的最大容量
if(freightList.calculateTotalWeight()>flight.getMaxcapacity()){
System.out.println("The flight with flight number:"+flight.getFlightNumber()+" has exceeded its load capacity and cannot carry the order.");
return;
} // 读取订单信息
Order order = new Order(
sc.nextLine(), // number
sc.nextLine() // date
); // 读取发件人信息
String senderAddress = sc.nextLine();
String senderName = sc.nextLine();
String senderTel = sc.nextLine();
Sender sender = new Sender(senderName, senderAddress, senderTel); // 读取收件人信息
String recipientAddress = sc.nextLine();
String recipientName = sc.nextLine();
String recipientTel = sc.nextLine();
Recipient recipient = new Recipient(recipientName, recipientAddress, recipientTel); //创建费率
Rate rate=new Rate();
// 创建支付类
Payment payment = new Payment(new WeChatPay(),freightList,rate); // 创建Show实例并显示
ShowOrder show = new ShowOrder(customer, freightList, flight, payment, sender, recipient, order);
show.showOrderInformation(); sc.close();

做好类的单一职责,降低耦合度

 在这段Main类的的main方法里面有超载的逻辑判断和输出没有很好的做到类的职责单一原则,可以将这个逻辑判断单拎出来。

添加合适的注释,增强代码可读性

 一些复杂的构造和调用方法并没有注释。这就会导致,当自己再次阅读代码或者别人查看代码时,会变得很吃力,所以需要给出合适的代码注释,增强代码的可读性。

五、总结

收获和建议:

收获

  在完成航空货物管理系统的过程中,最大的收获在于对面向对象设计原则的具象化理解与应用。通过两次迭代题目,我逐步体会到单一职责原则(SRP)如何通过拆分 “展示逻辑” 与 “业务逻辑”(如将订单信息输出从Order类剥离至ShowOrder类)降低类的复杂度;里氏代换原则(LSP)要求子类完全替代父类的场景(如Sender/Recipient继承People并实现统一接口),避免因子类行为差异导致的程序崩溃;开闭原则(OCP)则通过引入RateStrategy/DiscountStrategy接口,在新增货物类型或客户折扣时仅需扩展实现类而非修改原有代码,显著提升系统可维护性。

  此外,这次的航空货物管理系统也让我对 “接口编程” 思维有了一个具体化的了解。例如,将支付方式抽象为PayMethod接口,使支付宝、微信支付等具体实现可动态替换,这种 “面向抽象而非实现” 的设计极大减少了模块间的耦合。同时,通过FreightList类封装货物集合的操作,实现了数据存储与业务逻辑的分离,符合合成复用原则(CRP),避免了继承带来的紧耦合问题。

  最后虽然这次的题目让我收获颇丰,但还是有一些方面需要进一步的学习和研究的。比如:深入去了解,什么时候将方法抽象出来好,什么时候不要把方法抽象出来。跟深入的去了解这些不同设计所带来的优势和不同。在今后的编程当中更加主动去重视面向对象程序设计原则,规范自己的代码结构!

建议

最后根据这次迭代作业,给面向对象程序设计课题组的一些建议:

可以在迭代的题目集完全结束后给出规范合理的类设计结构给同学们学习、改进最终提升自己的编程能力

你在完成航空货物系统时遇到了哪些挑战?欢迎在评论区分享你的解决方案!感谢您的阅读!

题目集8~9总结性Blog的更多相关文章

  1. Java高级程序员(5年左右)面试的题目集

    Java高级程序员(5年左右)面试的题目集 https://blog.csdn.net/fangqun663775/article/details/73614850?utm_source=blogxg ...

  2. 题目集4~6的总结性Blog

    题目集4~6的总结性Blog (1)前言 在这三次作业中,主要考察了正则表达式以及类间的关系.在这三次作业中,相比之下,第四次以及第五次作业的难度明显高于第六次作业,题量与难度相较于以往的作业也有明显 ...

  3. 题目集7-9总结性Blog

    一.前言 通过对PTA的第七.八.九题目集的学习与总结,我感觉本三次题目集的题量不大,在完成范围之内.难度的话也一般,有难度,但是在解决范围之内,大多数较难的知识点可以通过自学(图书馆看书.看网课)的 ...

  4. KMP,Trie,AC自动机题目集

    字符串算法并不多,KMP,trie,AC自动机就是其中几个最经典的.字符串的题目灵活多变也有许多套路,需要多做题才能体会.这里收集了许多前辈的题目做个集合,方便自己回忆. KMP题目:https:// ...

  5. PTA7~9题目集总结与归纳

    前言: 总结三次题目集的知识点.题量.难度等情况. 目录: 题目集7(7-1).(7-2)两道题目的递进式设计分析总结 题目集8和题目集9两道ATM机仿真题目的设计思路分析总结 一. 题目集7(7-1 ...

  6. PTA4-6题目集总结与归纳

    前言: 继上篇blog所写的几种日期的求法,这次是把那几种聚合起来,即日期类的聚合设计.除下这类,一种是图形继承设计的3种变化,还有一种是3次对正则表达式的应用.当然,作为一个菜鸟,还是无法写成大佬的 ...

  7. 浙大版《C语言程序设计(第3版)》题目集 --总结

    浙大版<C语言程序设计(第3版)>题目集 此篇博客意义为总结pta上浙大版<C语言程序设计(第3版)>题目集所做题目的错误点,心得体会. 1.练习2-10 计算分段函数[1] ...

  8. PTA数据结构与算法题目集(中文) 7-43字符串关键字的散列映射 (25 分)

    PTA数据结构与算法题目集(中文)  7-43字符串关键字的散列映射 (25 分) 7-43 字符串关键字的散列映射 (25 分)   给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义 ...

  9. PTA数据结构与算法题目集(中文) 7-42整型关键字的散列映射 (25 分)

    PTA数据结构与算法题目集(中文)  7-42整型关键字的散列映射 (25 分) 7-42 整型关键字的散列映射 (25 分)   给定一系列整型关键字和素数P,用除留余数法定义的散列函数将关键字映射 ...

  10. PTA数据结构与算法题目集(中文) 7-41PAT排名汇总 (25 分)

    PTA数据结构与算法题目集(中文)  7-41PAT排名汇总 (25 分) 7-41 PAT排名汇总 (25 分)   计算机程序设计能力考试(Programming Ability Test,简称P ...

随机推荐

  1. Docker 容器的数据卷 以及 数据卷容器

    Docker 容器删除后,在容器中产生的数据还在吗? 答案是 不在 Docker 容器和外部机器可以直接交换文件吗? 在没有数据卷的情况下,答案是 不可以 如下图:外部机器:Windows系统(自己的 ...

  2. C#中固定编译时不确定数量的变量(相关话题fixed固定多个数组)

    以交错数组byte[][]为例. fixed无法固定byte[][],只能在编译时固定确定数量的变量. 交错数组byte[][]中的每一个byte[]可以采用GCHandle进行固定. int n = ...

  3. Halcon学习教程(二) 测量量测相关(点到线距离,线到线距离,轮廓线距离,一维测量,圆形测量,矩形测量等)

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/18740576 本篇讲一些测量用到的算子和实例,想了解更多就得去看看halcon实例里一维测量里 ...

  4. Grafana导入 json 文件的 dashboard 错误 Templating Failed to upgrade legacy queries Datasource xxx not found

    前言 编辑或者修改后的 dashboard 保存为 json 文件,在其他环境导入使用,报错 Failed to upgrade legacy queries Datasource xxxxxxx w ...

  5. go string转int strconv包

    前言 strconv 主要用于字符串和基本类型的数据类型的转换 s := "aa"+100 //字符串和整形数据不能放在一起 所以需要将 100 整形转为字符串类型 //+号在字符 ...

  6. 接口常用code码

    // Informational 1xx 100 => 'Continue', 101 => 'Switching Protocols', // Success 2xx 200 => ...

  7. 一次Java后端服务间歇性响应慢的问题排查记录

    分享一个之前在公司内其它团队找到帮忙排查的一个后端服务连接超时问题,问题的表现是服务部署到线上后出现间歇性请求响应非常慢(大于10s),但是后端业务分析业务日志时却没有发现慢请求,另外由于服务容器li ...

  8. [每日算法 - 华为机试] leetcode680. 验证回文串 II

    入口 力扣https://leetcode.cn/problems/valid-palindrome-ii/submissions/ 题目描述 给你一个字符串 s,最多 可以从中删除一个字符. 请你判 ...

  9. PHP文件上传封装

    class FileUploader { private $targetDirectory; private $allowedExtensions; private $maxFileSize; pub ...

  10. SQLServer中事务处理

    --将当前库存记录insert医废转移单中 --declare @Warehouse nvarchar(100); declare @Warehouse_JJRID nvarchar(100); de ...