第8,9次航空物流管理作业分析
前言
一、知识点总结
(一)第8次作业
题目及代码
点击查看题目和代码
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计,具体说明参看说明文件。
OO第九周作业题目说明.pdf
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。
客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:
-----------------------------------------
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
微信支付金额:
货物明细如下:
-----------------------------------------
明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
注:输出中实型数均保留1位小数。
输入样例:
在这里给出一组输入。例如:
10001
郭靖
13807911234
南昌航空大学
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
输出样例:
在这里给出相应的输出。例如:
客户:郭靖(13807911234)订单信息如下:
-----------------------------------------
航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
微信支付金额:3350.0
货物明细如下:
-----------------------------------------
明细编号 货物名称 计费重量 计费费率 应交运费
1 发电机 80.0 25.0 2000.0
2 信号发生器 45.0 30.0 1350.0
[https://images.ptausercontent.com/499d204b-fcef-4610-a9ca-c8fbf5e346d9.pdf]()
import java.util.*;
class Customer {
private String id;
private String name;
private String phone;
private String address;
public Customer(String id, String name, String phone, String address) {
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
}
public String getName() { return name; }
public String getPhone() { return phone; }
}
class Goods {
private String goodsId;
private String name;
private double width;
private double height;
private double weight;
private double length;
public Goods(String goodsId, String name, double width, double length, double height, double weight) {
this.goodsId = goodsId;
this.name = name;
this.width = width;
this.height = height;
this.weight = weight;
this.length = length;
}
public double getVolume() { return width * length * height; }
public double getWeight() { return weight; }
public double getMax() {
double volumeWeight = getVolume() / 6000;
return Math.max(weight, volumeWeight);
}
public double getRate() {
double max = getMax();
if (max < 20) return 35.0;
else if (max < 50) return 30.0;
else if (max < 100) return 25.0;
else return 15.0;
}
public double getPrice() { return getMax() * getRate(); }
public String getName() { return name; }
}
class Plane {
private String planeId;
private String startPort;
private String endPort;
private double maxWeight;
private String date;
public Plane(String planeId, String startPort, String endPort, double maxWeight, String date) {
this.planeId = planeId;
this.startPort = startPort;
this.endPort = endPort;
this.maxWeight = maxWeight;
this.date = date;
}
public String getPlaneId() { return planeId; }
public double getMaxWeight() { return maxWeight; }
}
class SendInfo {
private String orderId;
private String orderDate;
private String sendAddress;
private String receiveAddress;
private String sendPhone;
private String receivePhone;
private String sendName;
private String receiveName;
public SendInfo(String orderId, String orderDate, String sendAddress, String receiveAddress,
String sendPhone, String receivePhone, String sendName, String receiveName) {
this.orderId = orderId;
this.orderDate = orderDate;
this.sendAddress = sendAddress;
this.receiveAddress = receiveAddress;
this.sendPhone = sendPhone;
this.receivePhone = receivePhone;
this.sendName = sendName;
this.receiveName = receiveName;
}
public String getOrderId() { return orderId; }
public String getOrderDate() { return orderDate; }
public String getSendName() { return sendName; }
public String getSendPhone() { return sendPhone; }
public String getSendAddress() { return sendAddress; }
public String getReceiveName() { return receiveName; }
public String getReceivePhone() { return receivePhone; }
public String getReceiveAddress() { return receiveAddress; }
}
abstract class Payment {
public abstract String getMethod();
public abstract void pay(double amount);
}
class WechatPayment extends Payment {
@Override
public String getMethod() { return "微信支付金额:"; }
@Override
public void pay(double amount) {
System.out.printf("%.2f", amount);
}
}
class AlipayPayment extends Payment {
@Override
public String getMethod() { return "支付宝支付金额:"; }
@Override
public void pay(double amount) {
System.out.printf("Paid %.2f using Alipay.%n", amount);
}
}
class OrderAgent {
private Customer customer;
private Goods[] goods;
private Plane plane;
private SendInfo sendInfo;
private Payment payment;
public OrderAgent(Customer customer, Goods[] goods, Plane plane, SendInfo sendInfo) {
this.customer = customer;
this.goods = goods;
this.plane = plane;
this.sendInfo = sendInfo;
}
public void setPayment(Payment payment) {
this.payment = new WechatPayment();
}
public double getTotalWeight() {
double total = 0;
for (Goods g : goods) total += g.getMax();
return total;
}
public double getTotalPrice() {
double total = 0;
for (Goods g : goods) total += g.getPrice();
return total;
}
public void processOrder() {
double totalWeight = getTotalWeight();
if (totalWeight >= plane.getMaxWeight()) {
System.out.printf("The flight with flight number:%s has exceeded its load capacity and cannot carry the order.\n", plane.getPlaneId());
return;
}
System.out.printf("客户:%s(%s)订单信息如下:\n", customer.getName(), customer.getPhone());
System.out.println("-----------------------------------------");
System.out.println("航班号:" + plane.getPlaneId());
System.out.println("订单号:" + sendInfo.getOrderId());
System.out.println("订单日期:" + sendInfo.getOrderDate());
System.out.println("发件人姓名:" + sendInfo.getSendName());
System.out.println("发件人电话:" + sendInfo.getSendPhone());
System.out.println("发件人地址:" + sendInfo.getSendAddress());
System.out.println("收件人姓名:" + sendInfo.getReceiveName());
System.out.println("收件人电话:" + sendInfo.getReceivePhone());
System.out.println("收件人地址:" + sendInfo.getReceiveAddress());
System.out.printf("订单总重量(kg):%.1f\n", totalWeight);
setPayment(new WechatPayment());
System.out.printf("%s%.1f\n", payment.getMethod(), getTotalPrice());
System.out.printf("\n");
System.out.println("货物明细如下:");
System.out.println("-----------------------------------------");
System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
for (int i = 0; i < goods.length; i++) {
Goods g = goods[i];
System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",
i + 1,
g.getName(),
g.getMax(),
g.getRate(),
g.getPrice());
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String customerId = sc.next();
String customerName = sc.next();
String customerPhone = sc.next();
String customerAddress = sc.next();
int goodsNum = sc.nextInt();
Goods[] goods = new Goods[goodsNum];
for (int i = 0; i < goodsNum; i++) {
String goodsId = sc.next();
String goodsName = sc.next();
double width = sc.nextDouble();
double length = sc.nextDouble();
double height = sc.nextDouble();
double weight = sc.nextDouble();
goods[i] = new Goods(goodsId, goodsName, width, length, height, weight);
}
String planeId = sc.next();
String startPort = sc.next();
String endPort = sc.next();
String planeDate = sc.next();
double maxWeight = sc.nextDouble();
String orderId = sc.next();
String orderDate = sc.next();
String sendAddress = sc.next();
String sendName = sc.next();
String sendPhone = sc.next();
String receiveAddress = sc.next();
String receiveName = sc.next();
String receivePhone = sc.next();
Customer customer = new Customer(customerId, customerName, customerPhone, customerAddress);
Plane plane = new Plane(planeId, startPort, endPort, maxWeight, planeDate);
SendInfo sendInfo = new SendInfo(orderId, orderDate, sendAddress, receiveAddress, sendPhone, receivePhone, sendName, receiveName);
OrderAgent agent = new OrderAgent(customer, goods, plane, sendInfo);
agent.processOrder();
}
}
类图

分析图例

点击查看代码分析
Metrics Details For File '8.txt'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory C:\Users\86188\Desktop\新建文件夹\
Project Name Text
Checkpoint Name Baseline
File Name 8.txt
Lines 237
Statements 114
Percent Branch Statements 3.5
Method Call Statements 17
Percent Lines with Comments 0.0
Classes and Interfaces 6
Methods per Class 3.83
Average Statements per Method 2.52
Line Number of Most Complex Method 46
Name of Most Complex Method Goods.getRate()
Maximum Complexity 5
Line Number of Deepest Block 10
Maximum Block Depth 2
Average Block Depth 1.45
Average Complexity 1.18
--------------------------------------------------------------------------------------------
Most Complex Methods in 4 Class(es): Complexity, Statements, Max Depth, Calls
Customer.Customer() 1, 4, 2, 0
Customer.getName() 1, 1, 2, 0
Customer.getPhone() 1, 1, 2, 0
Goods.getMax() 1, 2, 2, 2
Goods.getName() 1, 1, 2, 0
Goods.getPrice() 1, 1, 2, 2
Goods.getRate() 5, 9, 2, 1
Goods.getVolume() 1, 1, 2, 0
Goods.getWeight() 1, 1, 2, 0
Goods.Goods() 1, 6, 2, 0
Plane.getMaxWeight() 1, 1, 2, 0
Plane.getPlaneId() 1, 1, 2, 0
Plane.Plane() 1, 5, 2, 0
SendInfo.getOrderDate() 1, 1, 2, 0
SendInfo.getOrderId() 1, 1, 2, 0
SendInfo.getReceiveAddress() 1, 1, 2, 0
SendInfo.getReceiveName() 1, 1, 2, 0
SendInfo.getReceivePhone() 1, 1, 2, 0
SendInfo.getSendAddress() 1, 1, 2, 0
SendInfo.getSendName() 1, 1, 2, 0
SendInfo.getSendPhone() 1, 1, 2, 0
SendInfo.SendInfo() 1, 8, 2, 0
--------------------------------------------------------------------------------------------
Block Depth Statements
0 7
1 49
2 58
3 0
4 0
5 0
6 0
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
由上面可以看出
. 方法复杂度
最高复杂度方法:Goods.getRate()(复杂度 5),逻辑为根据计费重量分档返回费率,分支结构清晰但可优化(如用枚举或策略模式替代if-else)。
平均复杂度:1.18,整体方法逻辑简单,多数方法为单分支或无分支(如getter方法)。
代码块深度:最大块深度 2(如getRate()中的if-else嵌套),逻辑层次浅,结构扁平。
核心类设计:
Customer类:封装客户基础信息(ID、姓名、电话、地址),提供基础信息查询方法。
Goods类:管理货物属性(ID、名称、尺寸、重量),计算体积重、计费重量、运费费率及运费,核心方法包括getMax()(取重量与体积重较大值)、getRate()(根据计费重量确定费率)、`getPrice()(计算运费)。
Plane类:描述航班信息(航班号、起降港口、日期、最大载重),提供航班号与最大载重查询。
SendInfo类:存储订单物流信息(订单号、日期、收发件人信息),提供全属性查询接口。
Payment抽象类:定义支付方式接口(getMethod()获取支付方式名称,pay()执行支付),具体实现类WechatPayment和AlipayPayment分别实现微信与支付宝支付逻辑。
OrderAgent类:协调客户、货物、航班、物流信息及支付方式,核心功能包括计算总重量与总运费、校验航班载重、生成订单详情及执行支付。
- 业务逻辑
- 输入处理:通过
Scanner读取客户、货物、航班、订单及支付信息,创建对应对象。 - 运费计算:货物运费基于“重量与体积重取最大值”计算,费率分档(<20kg:35元,<50kg:30元,<100kg:25元,≥100kg:15元)。
- 航班载重校验:若订单总重量超过航班最大载重,输出提示信息;否则生成订单详情,默认使用微信支付。
- 输入处理:通过
(二)第9次作业
点击查看题目和代码
航空快递以速度快、安全性高成为急件或贵重物品的首选。本题目要求对航空货运管理系统进行类设计,具体说明参看说明文件。
OO第十二周作业题目说明.pdf
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。
客户类型[可输入项:Individual/Corporate]
客户编号
客户姓名
客户电话
客户地址
货物类型[可输入项:Normal/Expedite/Dangerous]
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
支付方式[可输入项:Wechat/ALiPay/Cash]
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:
客户:姓名(电话)订单信息如下:
-----------------------------------------
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
[微信/支付宝/现金]支付金额:
货物明细如下:
-----------------------------------------
明细编号 货物名称 计费重量 计费费率 应交运费
1 ...
2 ...
注:输出中实型数均保留1位小数。
输入样例:
在这里给出一组输入。例如:
Corporate
10001
郭靖
13807911234
南昌航空大学
Expedite
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
ALiPay
输出样例:
在这里给出相应的输出。例如:
客户:郭靖(13807911234)订单信息如下:
-----------------------------------------
航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
支付宝支付金额:4360.0
货物明细如下:
-----------------------------------------
明细编号 货物名称 计费重量 计费费率 应交运费
1 发电机 80.0 40.0 3200.0
2 信号发生器 45.0 50.0 2250.0
[https://images.ptausercontent.com/b9cec79b-8012-4901-843e-3d48f27d28a6.pdf]()
import java.util.*;
class Customer {
private String type;
private String id;
private String name;
private String phone;
private String address;
public Customer(String type, String id, String name, String phone, String address) {
this.type = type;
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
}
public String getName() { return name; }
public String getPhone() { return phone; }
public double getDiscount() {
return type.equals("Corporate") ? 0.8 : 0.9;
}
}
class Goods {
private String id;
private String name;
private double width;
private double length;
private double height;
private double weight;
private String type;
public Goods(String type, String id, String name, double width, double length, double height, double weight) {
this.type = type;
this.id = id;
this.name = name;
this.width = width;
this.length = length;
this.height = height;
this.weight = weight;
}
public double getVolWeight(){return (width * length * height) / 6000;}
public double getChargeWeight(){return Math.max(weight, getVolWeight());}
public double getRate(){
double w = getChargeWeight();
switch (type) {
case "Normal":
if (w < 20) return 35;
else if (w < 50) return 30;
else if (w < 100) return 25;
else return 15;
case "Dangerous":
if (w < 20) return 80;
else if (w < 50) return 50;
else if (w < 100) return 30;
else return 20;
case "Expedite":
if (w < 20) return 60;
else if (w < 50) return 50;
else if (w < 100) return 40;
else return 30;
default: return 0;
}
}
public double getFreight() {
return getChargeWeight() * getRate();
}
public String getName() { return name; }
}
class Flight {
private String id;
private String origin;
private String dest;
private String date;
private double maxLoad;
public Flight(String id, String origin, String dest, String date, double maxLoad) {
this.id = id;
this.origin = origin;
this.dest = dest;
this.date = date;
this.maxLoad = maxLoad;
}
public String getId() { return id; }
public double getMaxLoad() { return maxLoad; }
}
class Order {
private String id;
private String date;
private String senderAddr;
private String receiverAddr;
private String senderPhone;
private String receiverPhone;
private String senderName;
private String receiverName;
public Order(String id, String date, String senderAddr, String receiverAddr,
String senderPhone, String receiverPhone, String senderName, String receiverName) {
this.id = id;
this.date = date;
this.senderAddr = senderAddr;
this.receiverAddr = receiverAddr;
this.senderPhone = senderPhone;
this.receiverPhone = receiverPhone;
this.senderName = senderName;
this.receiverName = receiverName;
}
public String getId() { return id; }
public String getDate() { return date; }
public String getSenderName() { return senderName; }
public String getSenderPhone() { return senderPhone; }
public String getSenderAddr() { return senderAddr; }
public String getReceiverName() { return receiverName; }
public String getReceiverPhone() { return receiverPhone; }
public String getReceiverAddr() { return receiverAddr; }
}
abstract class Payment {
public abstract String getMethod();
}
class WechatPay extends Payment {
public String getMethod() { return "微信"; }
}
class Alipay extends Payment {
public String getMethod() { return "支付宝"; }
}
class Cash extends Payment {
public String getMethod() { return "现金"; }
}
class OrderProcessor {
private Customer customer;
private Goods[] goods;
private Flight flight;
private Order order;
private Payment payment;
public OrderProcessor(Customer c, Goods[] g, Flight f, Order o, Payment p) {
customer = c;
goods = g;
flight = f;
order = o;
payment = p;
}
public double getTotalWeight() {
double sum = 0;
for (Goods g : goods) sum += g.getChargeWeight();
return sum;
}
public void process() {
double totalWeight = getTotalWeight();
if (totalWeight > flight.getMaxLoad()) {
System.out.printf("The flight with flight number:%s has exceeded its load capacity and cannot carry the order.\n", flight.getId());
return;
}
double base = 0;
for (Goods g : goods) base += g.getFreight();
double total = base * customer.getDiscount();
System.out.printf("客户:%s(%s)订单信息如下:\n", customer.getName(), customer.getPhone());
System.out.println("-----------------------------------------");
System.out.println("航班号:" + flight.getId());
System.out.println("订单号:" + order.getId());
System.out.println("订单日期:" + order.getDate());
System.out.println("发件人姓名:" + order.getSenderName());
System.out.println("发件人电话:" + order.getSenderPhone());
System.out.println("发件人地址:" + order.getSenderAddr());
System.out.println("收件人姓名:" + order.getReceiverName());
System.out.println("收件人电话:" + order.getReceiverPhone());
System.out.println("收件人地址:" + order.getReceiverAddr());
System.out.printf("订单总重量(kg):%.1f\n", totalWeight);
System.out.printf("%s支付金额:%.1f\n", payment.getMethod(), total);
System.out.println("\n货物明细如下:");
System.out.println("-----------------------------------------");
System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
for (int i = 0; i < goods.length; i++) {
Goods g = goods[i];
System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",
i+1, g.getName(), g.getChargeWeight(), g.getRate(), g.getFreight());
}
}
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String cType = sc.next();
String cId = sc.next();
String cName = sc.next();
String cPhone = sc.next();
String cAddr = sc.next();
String gType = sc.next();
int gCount = sc.nextInt();
Goods[] goods = new Goods[gCount];
for (int i=0; i<gCount; i++) {
String id = sc.next();
String name = sc.next();
double w = sc.nextDouble();
double l = sc.nextDouble();
double h = sc.nextDouble();
double weight = sc.nextDouble();
goods[i] = new Goods(gType, id, name, w, l, h, weight);
}
String fId = sc.next();
String fFrom = sc.next();
String fTo = sc.next();
String fDate = sc.next();
double fMax = sc.nextDouble();
String oId = sc.next();
String oDate = sc.next();
String sAddr = sc.next();
String sName = sc.next();
String sPhone = sc.next();
String rAddr = sc.next();
String rName = sc.next();
String rPhone = sc.next();
String pMethod = sc.next();
Payment p;
if (pMethod.equals("Wechat")) p = new WechatPay();
else if (pMethod.equals("ALiPay")) p = new Alipay();
else p = new Cash();
Customer c = new Customer(cType, cId, cName, cPhone, cAddr);
Flight f = new Flight(fId, fFrom, fTo, fDate, fMax);
Order o = new Order(oId, oDate, sAddr, rAddr, sPhone, rPhone, sName, rName);
OrderProcessor op = new OrderProcessor(c, goods, f, o, p);
op.process();
}
}
类图展示

分析图例

点击查看代码分析
Metrics Details For File '9.txt'
--------------------------------------------------------------------------------------------
Parameter Value
========= =====
Project Directory C:\Users\86188\Desktop\新建文件夹\
Project Name Text
Checkpoint Name Baseline
File Name 9.txt
Lines 218
Statements 138
Percent Branch Statements 13.0
Method Call Statements 13
Percent Lines with Comments 0.0
Classes and Interfaces 7
Methods per Class 3.43
Average Statements per Method 3.33
Line Number of Most Complex Method 40
Name of Most Complex Method Goods.getRate()
Maximum Complexity 14
Line Number of Deepest Block 44
Maximum Block Depth 4
Average Block Depth 1.92
Average Complexity 1.57
--------------------------------------------------------------------------------------------
Most Complex Methods in 5 Class(es): Complexity, Statements, Max Depth, Calls
Customer.Customer() 1, 5, 2, 0
Customer.getDiscount() 1, 1, 2, 1
Customer.getName() 1, 1, 2, 0
Customer.getPhone() 1, 1, 2, 0
Flight.Flight() 1, 5, 2, 0
Flight.getId() 1, 1, 2, 0
Flight.getMaxLoad() 1, 1, 2, 0
Goods.getChargeWeight() 1, 1, 2, 1
Goods.getFreight() 1, 1, 2, 2
Goods.getName() 1, 1, 2, 0
Goods.getRate() 14, 31, 4, 1
Goods.getVolWeight() 1, 1, 2, 0
Goods.Goods() 1, 7, 2, 0
Order.getDate() 1, 1, 2, 0
Order.getId() 1, 1, 2, 0
Order.getReceiverAddr() 1, 1, 2, 0
Order.getReceiverName() 1, 1, 2, 0
Order.getReceiverPhone() 1, 1, 2, 0
Order.getSenderAddr() 1, 1, 2, 0
Order.getSenderName() 1, 1, 2, 0
Order.getSenderPhone() 1, 1, 2, 0
Order.Order() 1, 8, 2, 0
WechatPay.getMethod() 1, 1, 2, 0
--------------------------------------------------------------------------------------------
Block Depth Statements
0 8
1 50
2 50
3 5
4 25
5 0
6 0
7 0
8 0
9+ 0
--------------------------------------------------------------------------------------------
由此看出:
方法复杂度:
最高复杂度方法:Goods.getRate ()(复杂度 14),逻辑为根据货物类型(Normal/Dangerous/Expedite)和计费重量双重条件分档返回费率,采用switch-case嵌套if-else实现,分支结构复杂(3 种类型 ×4 档重量判断),可优化为策略模式消除多层嵌套。
平均复杂度:1.57,整体方法逻辑中等,但核心业务方法(如getRate())复杂度显著拉高整体水平,其余方法(如getter、构造方法)逻辑简单。
代码块深度:最大块深度 4(getRate()中switch-case嵌套if-else),逻辑层次较深,可读性下降,但未超过合理范围(≤5),需通过重构简化条件判断。
-
核心类扩展
- Customer类增强:新增客户类型(
type)属性,区分企业客户(Corporate,折扣0.8)与个人客户(默认折扣0.9),提供getDiscount()计算折扣。 - Goods类增强:新增货物类型(
type)属性,分普通(Normal)、危险品(Dangerous)、加急(Expedite)三类,不同类型对应独立费率规则(如危险品费率更高)。 - Payment扩展:新增
Cash支付方式,实现现金支付逻辑;支付方式通过输入动态选择(微信/支付宝/现金)。 - OrderProcessor类:替代原OrderAgent类,新增折扣计算逻辑(总运费=基础运费×客户折扣),并支持动态指定支付方式。
- Customer类增强:新增客户类型(
-
业务逻辑升级
- 输入处理扩展:读取客户类型、货物类型及支付方式,支持更细粒度的业务场景。
- 运费计算增强:货物费率根据类型与计费重量双重判断(如加急件<20kg费率60元),总运费应用客户折扣。
- 支付方式动态化:通过输入参数选择支付方式,而非第8次作业默认微信支付。
二、题量与难度分析
| 作业 | 代码行数 | 核心难度点 | 面向对象设计要点 |
|---|---|---|---|
| 第8次 | ~237行 | 货物运费分档计算、航班载重校验 | 类职责单一(如Goods类专注运费计算)、抽象类与具体实现分离(Payment体系) |
| 第9次 | ~218行 | 多类型费率规则(货物+客户)、动态支付方式 | 继承与多态、不同货物类型的费率 |
三、代码结构与复杂度分析
(一)第8次作业
-
类与方法统计
- 共6个类(含抽象类与主类,代码结构清晰但部分方法逻辑集中(如
Goods.getRate()复杂度5)。 - 复杂度最高方法:`Goods.getRate()(复杂度5),包含多级条件判断。
- 代码块深度:最大块深度2,逻辑层次简单。
- 共6个类(含抽象类与主类,代码结构清晰但部分方法逻辑集中(如
-
设计细节
- 模块化计算:将体积重、计费重量、费率、运费计算拆解为独立方法,符合单一职责原则。
- 载重校验前置:在
processOrder()中先校验航班载重,避免无效计算,提升性能。
(二)第9次作业
-
类与方法统计
- 共7个类(含抽象类与主类),
Goods.getRate()复杂度激增为14。 - 复杂度最高方法:
Goods.getRate()(复杂度14),包含3个switch-case分支(货物类型),每个分支内嵌套4级if-else(重量分档)。 - 代码块深度:最大块深度4,逻辑复杂度显著提升。
- 共7个类(含抽象类与主类),
-
设计挑战
- 多维度条件判断:货物费率需同时考虑类型(3种)与重量(4档),导致
getRate()方法复杂度较高,可通过策略模式重构(如为每种货物类型定义独立费率策略类)。 - 支付方式扩展:新增
Cash支付时,仅需实现Payment接口,符合开闭原则,体现多态优势。
- 多维度条件判断:货物费率需同时考虑类型(3种)与重量(4档),导致
四、踩坑心得与优化
(一)问题思考
- 计量值问题:费率分档数值直接硬编码(虽然是题目要求),但可提取为类常量,提升可维护性。
- 支付逻辑硬编码:第8次作业中强制使用微信支付(这里虽然是题目要求),但第9次通过输入动态选择更合理,仍可进一步支持配置文件扩展。
(二)第8次作业特有问题
- 支付方式固定:未提供支付方式选择接口,灵活性不足。
- 货物类型单一:仅支持统一费率规则,无法应对多样化业务场景。
(三)第9次作业优化
- 重构费率计算:将
Goods.getRate()中的多层条件判断拆解,降低方法复杂度。
(四)边界条件遗漏:航班载重校验
- **第 8 次作业中,航班载重校验逻辑为if (totalWeight > flight.getMaxLoad()),未测试totalWeight == flight.getMaxLoad()的边界情况,导致不符合条件的订单也输出。
五、面向对象设计心得
(一)封装与职责分离
- 两次作业均通过类封装数据与行为(如
Goods类封装货物属性与计算逻辑),避免了数据暴露,符合封装原则。 - 第9次作业通过
OrderProcessor协调多个类(Customer、Goods、Flight),了解了控制类的调度职责,相比第8次OrderAgent更清晰了不少。
(二)继承与多态实践
Payment抽象类及其子类(WechatPayment、AlipayPayment、Cash)通过多态实现支付方式扩展,新增支付类型时无需修改现有代码,符合开闭原则。- 第9次作业中
Customer类通过type属性区分客户类型,使用条件判断实现折扣计算,可进一步通过继承(如CorporateCustomer子类)优化,消除if-else分支。
(三)复杂度控制
- 第8次作业复杂度集中在
Goods.getRate(),通过分档逻辑拆解可降低复杂度;第9次作业因货物类型扩展,复杂度显著上升,需通过设计模式重构化解。 - 代码块深度与循环嵌套层数需严格控制(如第9次
Goods.getRate()块深度4),避免逻辑过于复杂导致维护困难。
六、总结
(一)进步与提升
- 业务理解深化:从第8次单一费率到第9次多类型费率,逐步实现业务场景的精细化建模。
- 设计模式应用:第9次作业通过多态实现支付方式扩展,可以为后续功能扩展奠定基础。
(二)待改进方向
- 代码健壮性:补充输入校验、增加异常处理。
- 可维护性优化:提取常量、减少计量值,使用枚举类替代字符串类型,提升我的代码可读性。
通过这两次作业的迭代,逐步掌握了复杂业务场景下的面向对象设计方法,理解了类职责划分、抽象与具体分离的重要性。以后进一步结合设计模式,提升代码的可扩展性与可维护性,以应对更复杂的业务需求。
浙公网安备 33010602011771号