关于题目集8~9总结Blog

前言
本次习题集相较于上一次题目集的题目更简单一些,其核心目标在于考察学生对面向对象设计原则的理解与运用能力,尤其是继承和多态这两大关键概念的实际应用。虽然难度不算高,但还是有一些题目耗费了我挺多时间的,以及后续对于这些题目进行复盘,且后续复盘时暴露出一些设计与编码问题。
面向对象原则如下:
SRP(单一职责原则):一个类只负责单一功能。
OCP(开闭原则):应对扩展开放,对修改关闭。
LSP(里氏代换原则):子类能够替换其父类。
DIP(依赖倒转原则):高层模块不应该依赖低层模块,二者都应该依赖抽象。
CRP(合成复用原则):尽量使用合成或聚合,而不是继承。
ISP(接口隔离原则):客户端不应该依赖它不需要的接口。
LOD(迪米特法则):不和陌生人说话。
设计与分析
前两题较为简单,只放上类图,不细说了
第一题

第二题

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

报表内容

分支语句占比 0.7%,说明代码中分支逻辑占比相对低。
Classes and Interfaces:8个类和接口,表明代码结构中类型定义数量。
Methods per Class:平均每个类有3.88个方法,体现类的功能丰富度。
Average Statements per Method:每个方法平均3.79条语句,方法较为简洁。
Maximum Block Depth:最大嵌套深度为3,嵌套层次不算太深。
Average Block Depth:平均嵌套深度1.41,整体嵌套程度适中。
Average Complexity:平均复杂度1.03,代码整体复杂度较低。
类的具体实现
People(抽象类):定义了人员的基本属性接口(姓名、地址、电话)
Customer:继承自 People,代表客户,增加了客户编号属性
Sender:发件人信息
Recipient:收件人信息
Goods:货物类,包含名称、尺寸、重量等属性,计算计费重量
Plane:航班信息,包含航班号、起止机场、日期和最大载重
Order:订单信息,包含订单号和日期
Rate:运费计算类,根据货物重量确定费率和总运费
Print:打印订单详情,生成格式化的订单信息
Main:程序入口,处理用户输入并协调各对象之间的交互
抽象与继承:使用抽象类 People 定义人员基本属性,提高了代码的可扩展性和可维护性。
封装性:各实体类对内部数据进行了良好的封装,通过公共方法提供访问接口。(这里其实有一部分是没使用函数调用的,因为笔者当没注意到这个问题,直到后面的迭代复用代码时才发现这个问题)
单一职责:不同类负责不同的功能,如 Goods 负责计算计费重量,Rate 负责计算运费,符合单一职责原则。
第二次的前两道也偏简单,不介绍了


第三道是基于前一次第三题的一个迭代
航空公司或货代根据航线、货物类型、市场行情等制定(如CNY30/kg)。本次作业费率与货物类型有关,货物类型分为普通货物、危险货物和加急货物三种
计算公式:基础运费 = 计费重量 × 费率 × 折扣率
其中,折扣率是指不同的用户类型针对每个订单的运费可以享受相应的折扣,在本题中,用户分为个人用户和集团用户,其中个人用户可享受订单运费的9折优惠,集团用户可享受订单运费的8折优惠。

报表内容

总体和第一次差不多,由于条件增多复杂度有所上升
题目中添加的是关于客户货物以及支付方式增加了可选择项,且不同的选择项对于最后的付款金额也会有一定的影响,所以增加了一些如disc这样的变量来改变最后的总金额。至于货物类型的变化,则是在Rate内部进行修改。
同时,也发现了之前未发现的问题:即部分System.out.printf中未能使用函数调用,于是进行简单的修改。
优点:
抽象类与接口的使用较为合理(如 Pay、Goods),支持一定的扩展性(如新增支付方式、客户类型)。
基本遵循单一职责原则,类的职责划分较为清晰。
缺点:
类间耦合度高:
Print 类直接依赖多个具体类,main 方法包含过多业务逻辑。
优化:封装业务逻辑到服务类,通过数据类聚合信息,降低类间依赖。
改进建议
类设计问题:Customer 类继承 People 时重复定义属性,违反 DRY 原则,应直接继承 People 并新增 number 属性,避免代码冗余。
封装性不足:People 类的成员变量未声明为 private,外部可直接访问,需通过 private 修饰并仅暴露公共访问方法。(下次一定要先加一个private,防止再出现第一次第三题的这种情况)
多态未充分利用:Goods 子类未重写计费逻辑,导致 Rate 类通过字符串判断类型,耦合度高。可定义抽象方法 getRateType() 由子类实现,消除条件判断。
Print 类依赖具体类:Print 构造参数直接使用具体类,违反依赖倒转原则,可通过抽象类或接口解耦。
业务逻辑集中在 main 方法:对象创建、计算逻辑等应封装到服务类,减少 main 职责,提升模块化。
踩坑心得
1、第一次的第二道题虽然简单,但是在做题过程中被卡了6分,经过后续的研究,发现附件上说了雨刷系统有两种,于是对其进行添加修改,这也提醒了我在后续的写代码时,一定要先将代码看清楚。
2、第三题也出现了审题不清的情况,在判断商品重量时等号的条件出了问题,导致在这里也卡了一定的时间
3、在本次习题集中,虽然题目明确考察继承和多态的内容,但在实际编码过程中,对这两大概念的运用仍存在理解不够深入的问题。例如,在第三题中,对于不同商品类型的计费规则,未能充分利用多态特性,而是通过条件判断来实现,导致代码中仍存在一定的分支语句,违背了开闭原则。这反映未能灵活运用多态来消除条件判断,提高代码的可扩展性。
总结与反思
其实总体而言,在第8次题目集中,我并没有很好理解对于继承与多态的运用,这也导致了一部分面向对象设计原则没有很好的运用,也导致在后续的期中测试中虽然题目全写出来了,但还是被扣掉了20分,这也提醒我在后续的编码的过程中要尤其注意编码的规范。
而通过本次习题集的实践,深刻体会到面向对象设计原则是指导代码设计的核心准则。遵循这些原则能够有效提高代码的质量,使其具备更好的可维护性、可扩展性和可复用性。例如,单一职责原则使类的功能清晰明确,便于独立开发和测试;开闭原则允许在不修改现有代码的前提下扩展系统功能,降低了修改代码带来的风险;依赖倒转原则通过依赖抽象而非具体类,减少了类间的耦合度,提高了系统的灵活性。
在老师讲这几章的内容时,和我们说当程序员不能只会写代码,而经过这一次的代码训练,我更加能理解这句话的意义。这几个面向对象设计原则对于代码的设计和框架的搭建上都起到了非常大的作用,在未来,我也应该在不断敲代码的基础上,多去思考,更加注重这类统筹性的问题,不能只做一个写完代码就完事的码农,而是通过持续的练习和反思,逐步掌握面向对象的设计精髓,编写出更加健壮、灵活和易维护的软件系统。。

posted @ 2025-05-20 16:32  傅宇川  阅读(28)  评论(0)    收藏  举报