第二次blog作业
一,前言
两次关于航空货运管理系统的大作业,第一次为基础版,重点考查类的封装、计费逻辑实现及单一职责、合成复用原则的初步应用,涉及客户、航班、货物、订单等类的定义与基础输入输出流程,;第二次假设为深化版,在第一次基础上扩展设计原则深度,增加枚举、异常处理等进阶语法,代码复杂度与设计挑战提升。总的来说难度不是很大,但是代码量很多,要求码力也比之前高,完成还是需要花不少时间。但是自己一点一点打出来收获还是很大的。
二,设计过程
第一次作业
看题目给的输入和输出都很长,可见要求的代码有多少
下面是ac代码
点击查看代码
import java.util.*;
class Customer{
String id;
String name;
String phone;
String address;
public Customer(String id, String name, String phone, String address){
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
}
}
class Cargo{
String id;
String name;
double width;
double length;
double height;
double weight;
public Cargo(String id, String name, double width, double length, double height, double weight){
this.id = id;
this.name = name;
this.width = width;
this.length = length;
this.height = height;
this.weight = weight;
}
double getWeight(){
return Math.max(width * height * length/6000,weight);
}
double getV()
{
double x=getWeight();
if(x<20)return x*35;
if(x<50)return x*30;
if(x<100)return x*25;
return x*15;
}
}
class Flight{
String id;
String strat;
String end;
String date;
double maxweight;
public Flight(String id, String strat, String end, String date, double maxweight){
this.id = id;
this.strat = strat;
this.end = end;
this.date = date;
this.maxweight = maxweight;
}
}
class Order {
String id;
String date;
String address1;
String name1;
String phone1;
String address2;
String name2;
String phone2;
List<Cargo> cargo;
public Order(String id, String date, String address1, String name1, String phone1, String address2, String name2, String phone2,List<Cargo> cargo) {
this.id = id;
this.date = date;
this.address1 = address1;
this.name1 = name1;
this.phone1 = phone1;
this.address2 = address2;
this.name2 = name2;
this.phone2 = phone2;
this.cargo = cargo;
}
double getWeight(){
double res=0;
for(Cargo cargo :cargo){
res+=cargo.getWeight();
}
return res;
}
double getV(){
double res=0;
for(Cargo cargo :cargo){
res+=cargo.getV();
}
return res;
}
}
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入客户信息
String customerId = scanner.nextLine();
String customerName = scanner.nextLine();
String customerPhone = scanner.nextLine();
String customerAddress = scanner.nextLine();
Customer customer = new Customer(customerId, customerName, customerPhone, customerAddress);
// 输入货物信息
int cargoCount = Integer.parseInt(scanner.nextLine());
List<Cargo> cargoList = new ArrayList<>();
for (int i = 0; i < cargoCount; i++) {
String cargoId = scanner.nextLine();
String cargoName = scanner.nextLine();
double width = Double.parseDouble(scanner.nextLine());
double length = Double.parseDouble(scanner.nextLine());
double height = Double.parseDouble(scanner.nextLine());
double weight = Double.parseDouble(scanner.nextLine());
Cargo cargo = new Cargo(cargoId, cargoName, width, length, height, weight);
cargoList.add(cargo);
}
String flightNumber = scanner.nextLine();
String departureAirport = scanner.nextLine();
String arrivalAirport = scanner.nextLine();
String flightDate = scanner.nextLine();
double maxWeight = Double.parseDouble(scanner.nextLine());
Flight flight = new Flight(flightNumber, departureAirport, arrivalAirport, flightDate, maxWeight);
String orderId = scanner.nextLine();
String orderDate = scanner.nextLine();
String senderAddress = scanner.nextLine();
String senderName = scanner.nextLine();
String senderPhone = scanner.nextLine();
String recipientAddress = scanner.nextLine();
String recipientName = scanner.nextLine();
String recipientPhone = scanner.nextLine();
Order order = new Order(orderId, orderDate, senderAddress, senderName, senderPhone,
recipientAddress, recipientName, recipientPhone, cargoList);
if (order.getWeight() > flight.maxweight) {
System.out.printf("The flight with flight number:%s has exceeded its load capacity and cannot carry the order.\n", flightNumber);
return;
}
System.out.printf("客户:%s(%s)订单信息如下:\n", customerName, customerPhone);
System.out.println("-----------------------------------------");
System.out.printf("航班号:%s\n", flightNumber);
System.out.printf("订单号:%s\n", orderId);
System.out.printf("订单日期:%s\n", orderDate);
System.out.printf("发件人姓名:%s\n", senderName);
System.out.printf("发件人电话:%s\n", senderPhone);
System.out.printf("发件人地址:%s\n", ExpeditesenderAddress);
System.out.printf("收件人姓名:%s\n", recipientName);
System.out.printf("收件人电话:%s\n", recipientPhone);
System.out.printf("收件人地址:%s\n", recipientAddress);
System.out.printf("订单总重量(kg):%.1f\n", order.getWeight());
System.out.printf("微信支付金额:%.1f\n\n", order.getV());
// 输出货物明细
System.out.println("货物明细如下:");
System.out.println("-----------------------------------------");
System.out.println("明细编号 货物名称 计费重量 计费费率 应交运费");
for (int i = 0; i < cargoList.size(); i++) {
Cargo cargo = cargoList.get(i);
double chargeableWeight = cargo.getWeight();
double rate;
if (chargeableWeight < 20) {
rate = 35;
} else if (chargeableWeight < 50) {
rate = 30;
} else if (chargeableWeight < 100) {
rate = 25;
} else {
rate = 15;
}
System.out.printf("%d %s %.1f %.1f %.1f\n", i + 1, cargo.name, chargeableWeight, rate, cargo.getV());
}
}
}
核心实体类
Customer类
封装客户基本信息(ID、姓名、电话、地址),遵循单一职责原则。
Flight类
管理航班信息类
(航班号、起降机场、日期、最大载重),提供载重校验方法。
Cargo类 抽象基类,定义货物通用属性(尺寸、重量)和计费逻辑(体积重量、计费重量)。
NormalCargo类
普通货物子类,实现具体运费计算(基于重量分段计价)。
DangerousCargo类
危险品子类,扩展特殊货物的计费规则(如附加费)。
Order类
整合订单信息(发件人、收件人、航班)和货物列表,计算总重量与总费用。
sourcemonitor解析代码

行数:179 行
语句数:127 条
分支语句百分比:5.5% ,意味着约四分之一语句是分支逻辑(if-else)
方法调用语句数:42 条
注释行百分比:0.0% ,即代码无注释
类和接口数量:5 个
每个类的平均方法数:2.80 个
每个方法的平均语句数):10.43条
最复杂方法的行号:77 行,方法为 Elevator.getNextTargetFloor()
最大复杂度为43,方法也是Elevator.getNextTargetFloor()
最深代码块行号:91 行
最大代码块深度为5
平均代码块深度:2.93
平均复杂度:6.21
第二次作业
ac代码
点击查看代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Customer {
private String id;
private String name;
private String phone;
private String address;
private String type;
public Customer(String id, String name, String phone, String address, String type) {
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
this.type = type;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public String getType() {
return type;
}
}
class Cargo {
private String id;
private String name;
private double width;
private double length;
private double height;
private double weight;
private String type;
String getName()
{
return name;
}
public Cargo(String id, String name, double width, double length, double height, double weight, String type) {
this.id = id;
this.name = name;
this.width = width;
this.length = length;
this.height = height;
this.weight = weight;
this.type = type;
}
public double getVolumeWeight() {
return (width * length * height) / 6000;
}
public double getChargeableWeight() {
return Math.max(weight, getVolumeWeight());
}
public double getBaseCost() {
double rate = getRate();
return getChargeableWeight() * rate;
}
double getRate() {
double v=getChargeableWeight();
if ("Normal".equals(type)) {
if(v<20)return 35.0;
if(v<50)return 30;
if(v<100)return 25;
return 15;
} else if ("Expedite".equals(type)) {
if(v<20)return 60;
if(v<50)return 50;
if(v<100)return 40;
return 30;
} else if ("Dangerous".equals(type)) {
if(v<20)return 80;
if(v<50)return 50;
if(v<100)return 30;
return 20;
}
return 0.0;
}
}
class Flight {
private String id;
private String departureAirport;
private String arrivalAirport;
private String date;
private double maxWeight;
public Flight(String id, String departureAirport, String arrivalAirport, String date, double maxWeight) {
this.id = id;
this.departureAirport = departureAirport;
this.arrivalAirport = arrivalAirport;
this.date = date;
this.maxWeight = maxWeight;
}
public String getId() {
return id;
}
public String getDepartureAirport() {
return departureAirport;
}
public String getArrivalAirport() {
return arrivalAirport;
}
public String getDate() {
return date;
}
public double getMaxWeight() {
return maxWeight;
}
}
class Order {
private String id;
private String date;
private String senderAddress;
private String senderName;
private String senderPhone;
private String recipientAddress;
private String recipientName;
private String recipientPhone;
private String paymentMethod;
private List<Cargo> cargoList;
public Order(String id, String date, String senderAddress, String senderName,
String senderPhone, String recipientAddress, String recipientName,
String recipientPhone, String paymentMethod, List<Cargo> cargoList) {
this.id = id;
this.date = date;
this.senderAddress = senderAddress;
this.senderName = senderName;
this.senderPhone = senderPhone;
this.recipientAddress = recipientAddress;
this.recipientName = recipientName;
this.recipientPhone = recipientPhone;
this.paymentMethod = paymentMethod;
this.cargoList = cargoList;
}
public double getTotalWeight() {
double totalWeight = 0;
for (Cargo cargo : cargoList) {
totalWeight += cargo.getChargeableWeight();
}
return totalWeight;
}
public double getTotalCost(Customer customer) {
double totalCost = 0;
for (Cargo cargo : cargoList) {
totalCost += cargo.getBaseCost();
}
if ("Individual".equals(customer.getType())) {
totalCost *= 0.9;
} else if ("Corporate".equals(customer.getType())) {
totalCost *= 0.8;
}
return totalCost;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String customerType = scanner.nextLine();
String customerId = scanner.nextLine();
String customerName = scanner.nextLine();
String customerPhone = scanner.nextLine();
String customerAddress = scanner.nextLine();
Customer customer = new Customer(customerId, customerName, customerPhone, customerAddress, customerType);
String cargoType = scanner.nextLine();
int cargoCount = Integer.parseInt(scanner.nextLine());
List<Cargo> cargoList = new ArrayList<>();
for (int i = 0; i < cargoCount; i++) {
String cargoId = scanner.nextLine();
String cargoName = scanner.nextLine();
double width = Double.parseDouble(scanner.nextLine());
double length = Double.parseDouble(scanner.nextLine());
double height = Double.parseDouble(scanner.nextLine());
double weight = Double.parseDouble(scanner.nextLine());
Cargo cargo = new Cargo(cargoId, cargoName, width, length, height, weight, cargoType);
cargoList.add(cargo);
}
String flightId = scanner.nextLine();
String departureAirport = scanner.nextLine();
String arrivalAirport = scanner.nextLine();
String flightDate = scanner.nextLine();
double maxWeight = Double.parseDouble(scanner.nextLine());
Flight flight = new Flight(flightId, departureAirport, arrivalAirport, flightDate, maxWeight);
String orderId = scanner.nextLine();
String orderDate = scanner.nextLine();
String senderAddress = scanner.nextLine();
String senderName = scanner.nextLine();
String senderPhone = scanner.nextLine();
String recipientAddress = scanner.nextLine();
String recipientName = scanner.nextLine();
String recipientPhone = scanner.nextLine();
String paymentMethod = scanner.nextLine();
Order order = new Order(orderId, orderDate, senderAddress, senderName, senderPhone, recipientAddress, recipientName, recipientPhone, paymentMethod, cargoList);
if (order.getTotalWeight() > flight.getMaxWeight()) {
System.out.printf("The flight with flight number:%s has exceeded its load capacity and cannot carry the order.", flight.getId());
System.exit(0);
} else {
System.out.printf("客户:%s(%s)订单信息如下:\n", customer.getName(), customer.getPhone());
System.out.println("-----------------------------------------");
System.out.printf("航班号:%s\n", flight.getId());
System.out.printf("订单号:%s\n", orderId);
System.out.printf("订单日期:%s\n", orderDate);
System.out.printf("发件人姓名:%s\n", senderName);
System.out.printf("发件人电话:%s\n", senderPhone);
System.out.printf("发件人地址:%s\n", senderAddress);
System.out.printf("收件人姓名:%s\n", recipientName);
System.out.printf("收件人电话:%s\n", recipientPhone);
System.out.printf("收件人地址:%s\n", recipientAddress);
System.out.printf("订单总重量(kg):%.1f\n", order.getTotalWeight());
if(paymentMethod.equals("Wechat"))System.out.printf("微信");
if(paymentMethod.equals("ALiPay"))System.out.printf("支付宝");
if(paymentMethod.equals("Cash"))System.out.printf("现金");
System.out.printf("支付金额:%.1f\n\n", order.getTotalCost(customer));
System.out.println("货物明细如下:");
System.out.println("-----------------------------------------");
System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
for (int i = 0; i < cargoList.size(); i++) {
Cargo cargo = cargoList.get(i);
System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n", i + 1, cargo.getName(), cargo.getChargeableWeight(), cargo.getRate(), cargo.getBaseCost());
}
}
}
}
1. Customer 类
属性:客户编号、姓名、电话、地址、类型(Individual/Corporate)。
作用:
区分客户类型以应用不同折扣(个人 9 折、企业 8 折)。
提供客户基本信息用于订单报表输出。
2. Cargo 类
属性:货物编号、名称、宽度、长度、高度、实际重量、类型(Normal/Expedite/Dangerous)。
核心方法:
getVolumeWeight():计算体积重量(长 × 宽 × 高 ÷6000)。
getChargeableWeight():取体积重量与实际重量的较大值作为计费重量。
getBaseCost():根据货物类型和计费重量计算基础运费(分段费率)。
3. Flight 类
属性:航班号、起飞机场、降落机场、日期、最大载重量。
作用:
存储航班基础信息。
提供getMaxWeight()方法校验订单总重量是否超过航班载重限制。
4. Order 类
属性:订单号、日期、收发件人信息、支付方式、货物列表。
核心方法:
getTotalWeight():累加所有货物的计费重量,计算订单总重量。
getTotalCost(Customer):根据客户类型计算总费用(基础运费 + 折扣)。
5. Main 类
职责:
按顺序读取用户输入(客户、货物、航班、订单信息)。
实例化各业务对象,调用Flight校验载重。
格式化输出订单信息和货物明细,处理载重超限异常。
sourcemonitor解析代码

行数:271 行
语句数:197 条
分支语句百分比:11.2% ,意味着约四分之一语句是分支逻辑(if-else)
方法调用语句数:67 条
注释行百分比:0.0% ,即代码无注释
类和接口数量:5 个
每个类的平均方法数:3.80 个
每个方法的平均语句数):9.43条
最复杂方法的行号:77 行,方法为 Elevator.getNextTargetFloor()
最大复杂度为43,方法也是Elevator.getNextTargetFloor()
最深代码块行号:81 行
最大代码块深度为5
平均代码块深度:2.93
平均复杂度:6.21
3,踩坑心得
一、输入输出处理的坑
- 输入顺序混乱
坑:未严格按照题目要求的顺序输入数据,导致Scanner读取错位(如先输入货物数量却先读取货物类型)。
心得:
用注释明确标注输入步骤(如 “// 输入客户信息”“// 输入货物信息”)。
每次读取后打印临时变量值,调试确认输入顺序正确(如System.out.println("读取的货物数量:" + cargoCount))。 - 数据类型转换错误
坑:字符串转数值时未处理非法输入(如输入字母导致NumberFormatException)。
心得:
增加异常捕获(try-catch),提示用户重新输入合法数值。
输入后立即校验范围(如if (weight <= 0) throw new IllegalArgumentException("重量必须为正数"))。 - 输出格式控制
坑:浮点型输出未保留指定小数位(如%.1f写成%.0f),或对齐混乱(制表符\t使用不当)。
心得:
使用System.out.printf("%.1f", value)强制格式化,提前测试边界值(如计费重量为整数时显示.0)。
用文本编辑器先模拟表格对齐(如 Excel 或 Markdown 表格),再转化为printf格式。
4,改进建议
一、设计原则优化
单一职责原则
拆分Cargo类中费率计算逻辑,避免同时处理属性和计费规则。
将支付方式输出逻辑从Order类分离,避免职责混杂。
开闭原则
用策略模式封装货物费率计算(定义接口FreightStrategy,不同类型货物实现接口)。
新增货物类型时通过扩展策略类实现,不修改原有代码。
里氏代换原则
若存在子类(如危险品),确保父类Cargo的核心方法(如计费)行为一致,子类可安全替换父类。
合成复用原则
避免继承滥用,通过组合(如Order包含Cargo列表)实现代码复用。
二、代码规范与可读性
命名规范
方法名更直观:getV()→calculateFreight(),strat→departureAirport。
类名、变量名遵循驼峰命名(如cargoCount而非cargoCount,已正确)。
数据封装
所有字段声明为private,通过public getter/setter访问(如Customer类添加getType())。
注释补充
关键逻辑添加注释:费率分段依据、折扣规则、体积重量公式来源。
5,总结
写大作业不要骄躁,一步一步来,才能收获多
浙公网安备 33010602011771号