航空货运管理系统总结blog
一前言
在这两周的pta学习中,主要考察了我们对类的设计,继承,接口,多态以及类设计的单一职责原则、里氏代换原则、开闭原则、合成复用原则等知识点进行考察,算法思维难度下降。比如第8次pta中的雨刷程序功能扩展设计题目,提供两个系统,要求我们运用多态实现系统的可扩展性;第8次pta中的_点线面问题要求抽象出Element父类,Point类,Line类,Plane类为子类,继承Element类,最终通过定义一个Element类的抽象方法,分别使用该方法display()输出子类的信息,从而实现多态的特性,同时还考察了泛型(泛型是编程语言中一种允许在定义类、接口或方法时使用类型参数的特性)和ArrayList列表的使用。
二设计与分析
第8次航空货运管理系统分析
本题要求根据真实的航空货运管理系统,从键盘依次输入填写订单需要提供的信息,然后分别生成订单信息报表及货物明细报表。
首先这个题目要进行类的划分和设计,明白不同类之间的关系,既要满足单一职责原则,也要符合里氏代换原则、开闭原则以及合成复用原则。
最终类图效果:
一共设计了12个类,其中Pay这个父类下有Alipay类和Wechat类两个子类,Person父类以及其Sender,Recipient,和Customer子类,使用继承能够很好避免代码重复,提高复用性。同时还包括order和orderItem类,Product类,Controller类和Flight类,每个类各司其职,尽量做到最少知识原则,符合单一职责原则
点击查看代码
class Order {
private String date;
private String ID;
public Order() {
}
public Order(String ID, String date) {
this.ID = ID;
this.date = date;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
}
Order类只负责订单号,订单日期的getter和setter,其内部复杂的增减商品都放在了OrderItem类中,将职能细分,符合单一变量职责原则
点击查看代码
class OrderItem {
private ArrayList<Product> list = new ArrayList<Product>();
public OrderItem() {
}
public OrderItem(ArrayList<Product> list) {
this.list = list;
}
public ArrayList<Product> getList() {
return list;
}
public double getTotalWeight() {
double sum = 0;
for (Product product : list) {
sum += product.getFinalWeight();
}
return sum;
}
public double getTotalFreight() {
double sum = 0;
for (Product product : list) {
sum += product.getFreight();
}
return sum;
}
public void setList(ArrayList<Product> list) {
this.list = list;
}
public void add(Product product) {
list.add(product);
}
}
OederItem类中有ArrayList列表,其中泛型为Product,这个类主要负责查看订单的商品,计算总的商品重量和支付总金额
SourceMonitor代码分析:
- 总行数 473,语句数 221,规模适中。
- 包含 6 个类或接口,平均每类 11.33 个方法,方法数量较多但平均每方法仅 3.04 条语句,代码较简洁
- 最复杂方法为 Sender.Sender(),复杂度 1,深度最深块行号 11,最大块深度 2,整体结构简单。
- 释行占比仅 1.9%,严重不足,代码可读性与可维护性差,需补充注释
踩坑心得: - 数据传入时会有些对不上,这个问题是输入时多余换行符导致的,在代码中加入scanner.nextLine(); 消耗掉残留的换行符
- 类设计时不够精细,导致一个类的功能过多,最后调用时出现混乱,解决这个问题的关键还是在开始写代码前应做好类设计,将类的职能分开,简化,比如增加Controller类,在这个类中调用其他类,完成判断是否能再加行李的功能
- 参数传入时因为没有对传入的参数进行更新,导致参数一直不会变化,最后导致结果,这个问题也是因为对代码的不熟悉,导致没有及时更新数据
第9次航空货运管理系统分析
这次问题要求对货物类型进一步细分为普通货物、危险货物和加急货物三种,不同的货物其费率不同,用户类型也要求细分为个人用户和集团用户,其中个人用户可享受订单运费的9折优惠,集团用户可享受订单运费的 8 折优惠,支付方式增加现金支付。
这里增加的现金支付只需要在之前的类基础上多增加一个CashPayment类,同样继承自Pay父类。
而货物类型的细分则要求将这三种货物的共有属性和方法抽象出来,做成一个类,然后细分的三个类分别继承这个抽象类
用户的区分也只需要加入这两个类即可
最终类图呈现:
在上一次类设计的基础上增加了CashPayment类,NormalProduct类,UrgentProduct类,DangerProduct类,CompanyCustomer类,IndivisualCustomer类,
SourceMonitor中解析:
存在 3 个类,表明代码有一定的结构划分,并非所有功能都集中在一个类中,体现了基本的面向对象设计思想,便于初步的功能区分与管理。
调用次数为 58,说明方法之间存在一定的协作,功能有初步的分解,而非全部逻辑集中在少数几个方法中。
注释比例仅 3.1%,代码缺乏必要的说明,不利于后续维护、调试和团队协作。
最大复杂度为 12(超过建议值 10),表明部分方法逻辑复杂,需拆分复杂方法,遵循单一职责原则,降低圈复杂度。
踩坑心得:
- 增加了输入,还是有些信息对不上的情况,仔细检查输入语句与输入是否吻合,一些换行符要及时删去
- 开始时没有注意格式,答案也错误,应付总金额是折扣后的而订单明细打印的却是没算折扣之前的金额,一直在这个卡顿,不知道为什么还是错误。归根到底还是自己没有仔细审核题目要求,一些地方的输出也没有注意
三改进建议
- 第一题中计算费率比较简单,但之后加入多种货物不同的计算方法时,计算费率难度加大,应该将计算费率的方法抽象出来,做成一个接口,实现代码的可复用
- 输入匹配时一直搞不清楚是否对应上,特别是像这次的输入较多情况,写代码时应仔细观察,一一对应
- 代码不是越少越好,而是职责越清晰越好。合理的分层能让系统更易维护、扩展和测试。 在写代码前一定要明确写几个类,类与类之间的关系是什么,类的作用是什么。
四总结与反思
这次总体问题不难,但也要格外细心,仔细阅读输出格式,不要在一些格式问题上反复出错,其次得到比较深刻的醒悟就是一定要在开始写代码前就应该思考自己要做几个类,每个类之间的关系是什么,每个类的功能是什么,这样在写的时候才不会磕磕绊绊,也会省去很多不必要的麻烦。