第二次Blog-对PTA题目集8~9航空货运管理系统分析

航空货运管理系统总结

前言

题目集8和9围绕航空货运管理系统展开,从基础类设计到复杂的抽象类和继承与多态。题目集8侧重基础类的设计与封装,知识点包括:考察类的设计原则,要求符合单一职责、里氏代换、开闭原则、合成复用原则等几大设计原则;简单计费逻辑实现等,题量适中,难度中等。题目集9要求引入抽象类、继承、多态等,要求实现客户分类(个人/企业)、货物类型(普通/加急/危险品)进行不同的处理,题量略有增加,难度显著提升,尤其是对类设计有更高要求。

第一次航空货运管理系统代码分析

题目分析

题目要求按照如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。然后分别生成订单信息报表及货物明细报表,如果订单中货物重量超过航班剩余载重量,程序输出报错信息并且终止。
要求符合面向对象设计:单一职责原则(40%)、里氏代换原则(20%)、开闭原则(20%)、合成复用原则(20%)。

附上我的源码和源码分析

1.类图

1.Main类:

读取客户信息、货物数据、航班信息及订单信息。
创建 Customer、Goods、Plane、Order 对象。
通过 Controller 计算运费、校验载重、输出结果。
调用支付方式提示(如微信支付)。

2.Customer 类

作用:属于实体类,管理客户信息,包括发货人和收货人。
id:客户唯一标识。
name、phone、address:客户姓名、电话和地址。
goodNum:客户关联的货物数量。
功能:
提供多个构造方法,支持不同场景下的创建客户对象(如创建收件人)。
通过 getter/setter方法 实现属性的封装与访问。

3.Goods 类

作用:属于实体类,管理货物信息及运费计算逻辑。
属性:
name、width、length、height、weight:货物名称、尺寸和重量。
volume:自动计算体积(width * length * height)。
W:计费重量(实际重量与体积重量的较大值)。
rate、price:运费费率和总价。
功能:
根据体积与重量计算计费重量(W = max(weight, volume/6000))。
提供费率设置和运费计算逻辑(price = W * rate)。

4.Plane 类

作用:属于实体类,管理航班信息及载重限制。
属性:
id:航班号。
place1、place2:出发地和目的地。
time:航班时间。
maxWeight:最大载重量。
功能:
提供航班基础信息的封装,用于后续校验订单是否超重。

5.Order 类

作用:管理订单信息,关联客户、货物及航班。
属性:
id、time:订单编号和创建时间。
customer1、customer2:发件人和收件人(均为 Customer 对象)。
goodsList:订单包含的货物列表。
功能:
支持货物列表的增删查改。
存储订单的完整上下文信息。

6.Payment 抽象类及其子类

作用:定义支付方式。
子类:
WeChat:实现微信支付的提示逻辑(输出“微信支付金额”)。
Alipay:实现支付宝支付的提示逻辑(输出“支付宝支付金额”)。
功能:
通过抽象类提供统一的支付接口,子类实现具体支付方式。

7.Controller 类

作用:控制类,核心算法处理。
功能:
费用计算(calculateRate):根据货物体积和重量计算运费,并累加总重量。
载重校验(Check):检查订单总重量是否超过航班最大载重。
信息展示(Show1、Show2):输出订单详情和货物明细。
整合 Plane、Order、Customer 和 Goods 的数据,并且对整合的数据进行处理。

2.代码分析

1.源码
点击查看代码
import java.util.*;

class Customer{
    private String id;
    private String name;
    private String phone;
    private String address;
    private double goodNum;

    public Customer() {

    }
    public Customer(String id, String name, String phone, String address, double goodNum) {
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.address = address;
        this.goodNum = goodNum;
    }
    public Customer( String name, String phone, String address) {
        this.name = name;
        this.phone = phone;
        this.address = address;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public double getGoodNum() {
        return goodNum;
    }
    public void setGoodNum(double goodNum) {
        this.goodNum = goodNum;
    }
}
class Goods{
    private String name;
    private double width;
    private double length;
    private double height;
    private double weight;
    private double volume=0;
    private double rate=0;
    private double price=0;
    private double W;

    public Goods() {
        super();
    }
    public void SetW(double W){
        this.W=W;
    }
    public double GetW(){
        return this.W;
    }
    public Goods(String name, double width, double length, double height, double weight) {
        this.name = name;
        this.width = width;
        this.length = length;
        this.height = height;
        this.weight = weight;
    }
    public void SetPrice(double price){
        this.price=price;
    }
    public double GetPrice(){
        return this.price;
    }
    public void SetRate(double rate){
        this.rate=rate;
    }
    public double GetRate(){
        return this.rate;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getWidth() {
        return width;
    }
    public void setWidth(double width) {
        this.width = width;
    }
    public double getLength() {
        return length;
    }
    public void setLength(double length) {
        this.length = length;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    public double getVolume() {
        return width * length * height;
    }
}

class Plane{
    private String id;
    private String place1;
    private String place2;
    private String time;
    private double maxWeight;

    public Plane() {

    }
    public Plane(String id, String place1, String place2, String time, double maxWeight) {
        this.id = id;
        this.place1 = place1;
        this.place2 = place2;
        this.time = time;
        this.maxWeight = maxWeight;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPlace1() {
        return place1;
    }
    public void setPlace1(String place1) {
        this.place1 = place1;
    }
    public String getPlace2() {
        return place2;
    }
    public void setPlace2(String place2) {
        this.place2 = place2;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public double getMaxWeight() {
        return maxWeight;
    }
    public void setMaxWeight(double maxWeight) {
        this.maxWeight = maxWeight;
    }
}
class Order{
    private String id;
    private String time;
    private Customer customer1;
    private Customer customer2;
    private LinkedList<Goods> goodsList = new LinkedList<>();
    private double totalPrice=0;

    public Order() {

    }
    public Order(String id, String time,Customer customer1, Customer customer2, LinkedList<Goods> goodsList) {
        this.id = id;
        this.time = time;
        this.customer1 = customer1;
        this.customer2 = customer2;
        this.goodsList = goodsList;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public Customer getCustomer1() {
        return customer1;
    }
    public void setCustomer1(Customer customer1) {
        this.customer1 = customer1;
    }
    public Customer getCustomer2() {
        return customer2;
    }
    public void setCustomer2(Customer customer2) {
        this.customer2 = customer2;
    }
    public void setGoodsList(LinkedList<Goods> goodsList) {
        this.goodsList = goodsList;
    }
    public LinkedList<Goods> getGoodsList() {
        return goodsList;
    }
    public void addGoods(Goods goods){
        goodsList.add(goods);
    }
}
abstract class  Payment{
    private String option;

    public Payment() {

    }
    public Payment(String option) {
        this.option = option;
    }
    public void setOption(String option) {
        this.option = option;
    }
    public abstract void getOption();
}
class WeChat extends Payment{
    WeChat() {
        super();
    }
    @Override
    public void getOption() {
        System.out.print("微信支付金额:");
    }
}
class Alipay extends Payment{
    Alipay() {
        super();
    }
    @Override
    public void getOption() {
        System.out.print("支付宝支付金额:");
    }
}

class Controller{
    private Plane plane;
    private Order order;
    private Customer customer1;
    private Customer customer2;
    private Customer customer;
    private LinkedList<Goods> goodsList = new LinkedList<>();

    double totalWeight=0;
    public Controller() {

    }
    public Controller(Plane plane, Order order, Customer customer1, Customer customer2,Customer customer) {
        this.plane = plane;
        this.order = order;
        this.customer1 = customer1;
        this.customer2 = customer2;
        this.goodsList = order.getGoodsList();
        this.customer=customer;
    }

    public void calculateRate(){
        for(int i=0;i<goodsList.size();i++){
            double w1 = goodsList.get(i).getWeight();
            double w2 =1.0*goodsList.get(i).getVolume()/6000;
            if(w1<w2){
                w1=w2;
            }
            goodsList.get(i).SetW(w1);
            if(w1<20){
                goodsList.get(i).SetRate(35);
            }
            else if(w1>=20 && w1<50){
                goodsList.get(i).SetRate(30);
            }
            else if(w1>=50 && w1<100){
                goodsList.get(i).SetRate(25);
            }
            else if(w1>=100){
                goodsList.get(i).SetRate(15);
            }
            goodsList.get(i).SetPrice(w1*goodsList.get(i).GetRate());
            totalWeight+=w1;
        }
    }
    public double getTotalPrice(){
        double totalPrice=0;
        for(int i=0;i<goodsList.size();i++){
            totalPrice+=goodsList.get(i).GetPrice();
        }
        return totalPrice;
    }
    public boolean Check(){
        if(totalWeight>plane.getMaxWeight()){
            return false;
        }
        return true;
    }
    public void Show1(){
        System.out.println("客户:"+customer.getName()+"("+ customer.getPhone()+")订单信息如下:");
        System.out.println("-----------------------------------------");
        System.out.println("航班号:" + plane.getId());
        System.out.println("订单号:" + order.getId());
        System.out.println("订单日期:" + order.getTime());
        System.out.println("发件人姓名:" + order.getCustomer1().getName());
        System.out.println("发件人电话:" + order.getCustomer1().getPhone());
        System.out.println("发件人地址:" + order.getCustomer1().getAddress());
        System.out.println("收件人姓名:" + order.getCustomer2().getName());
        System.out.println("收件人电话:" + order.getCustomer2().getPhone());
        System.out.println("收件人地址:" + order.getCustomer2().getAddress());
        System.out.println("订单总重量(kg):" + totalWeight);
    }
    public void Show2(){

        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.printf("明细编号\t货物名称\t计费重量\t计费费率\t应交运费\n");
        for(int i = 0; i < goodsList.size(); i++){
            System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f",
                    i + 1,
                    goodsList.get(i).getName(),
                    goodsList.get(i).GetW(),
                    goodsList.get(i).GetRate(),
                    goodsList.get(i).GetPrice()
            );
            if(i!=goodsList.size()-1){
                System.out.printf("\n");
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String customerId = "";
        String customerName = "";
        String customerPhone = "";
        String customerAddress = "";
        double customerGoodsNum = 0;
        customerId = scanner.nextLine();
        customerName = scanner.nextLine();
        customerPhone = scanner.nextLine();
        customerAddress = scanner.nextLine();
        customerGoodsNum = scanner.nextDouble();
        scanner.nextLine();
        LinkedList<Goods> goodsList = new LinkedList<>();
        Customer customer = new Customer(customerId, customerName, customerPhone, customerAddress, customerGoodsNum);
        for(int i = 0; i < customerGoodsNum; i++){
            String goodsName = "";
            double goodsWidth = 0;
            double goodsLength = 0;
            double goodsHeight = 0;
            double goodsWeight = 0;
            scanner.nextLine();
            goodsName = scanner.nextLine();
            goodsWidth = scanner.nextDouble();
            goodsLength = scanner.nextDouble();
            goodsHeight = scanner.nextDouble();
            goodsWeight = scanner.nextDouble();
            scanner.nextLine();
            Goods goods = new Goods(goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
            goodsList.add(goods);
        }
        String PlaneId = "";
        String place1 = "";
        String place2 = "";
        String time = "";
        double maxWeight = 0;
        PlaneId = scanner.nextLine();
        place1 = scanner.nextLine();
        place2 = scanner.nextLine();
        time = scanner.nextLine();
        maxWeight = scanner.nextDouble();
        scanner.nextLine();
        Plane plane = new Plane(PlaneId, place1, place2, time, maxWeight);
        String orderId = "";
        String orderTime = "";
        String orderAddress1 = "";
        String orderName1 = "";
        String orderPhone1 = "";
        String orderAddress2 = "";
        String orderName2 = "";
        String orderPhone2 = "";
        orderId = scanner.nextLine();
        orderTime = scanner.nextLine();
        orderAddress1 = scanner.nextLine();
        orderName1 = scanner.nextLine();
        orderPhone1 = scanner.nextLine();
        orderAddress2 = scanner.nextLine();
        orderName2 = scanner.nextLine();
        orderPhone2 = scanner.nextLine();
        Customer customer1 = new Customer(orderName1, orderPhone1, orderAddress1);
        Customer customer2 = new Customer(orderName2, orderPhone2, orderAddress2);
        Order order = new Order(orderId, orderTime, customer1, customer2, goodsList);
        Controller controller = new Controller(plane, order, customer1, customer2,customer);
        controller.calculateRate();
        if(!controller.Check()){
            System.out.println("The flight with flight number:"+plane.getId()+" has exceeded its load capacity and cannot carry the order.");
            return ;
        }
        controller.Show1();
        WeChat weChat = new WeChat();
        weChat.getOption();
        System.out.println(controller.getTotalPrice());
        System.out.println("");
        controller.Show2();
    }
}

2.SourceMonitor代码分析:


数据分析

行数(Lines):432
语句数(Statements):256
分支语句百分比(% Branches):1.6
方法调用语句(Calls):58
注释行百分比(% Comments):0.0
类和接口数量(Classes):7
每个类的方法数(Methods/Class):9.00
平均每个方法的语句数(Avg Stmts/Method):2.49
最大复杂度(Max Complexity):3
最大块深度(Max Depth):4
平均块深度(Avg Depth):1.66
平均复杂度(Avg Complexity):1.06

分析

代码的基本结构:7 个类,每个类平均 9 个方法,说明类的规模较大,每个类包含较多方法。平均每个方法的语句数是 2.49,非常少,方法比较简单,功能单一。最大复杂度是 3,代码的逻辑复杂度低,没有复杂的条件判断或循环嵌套。平均复杂度 1.06 也很低,整体代码复杂度不高。分支语句百分比 1.6%,说明分支结构很少,代码流程较为线性。注释行百分比 0,代码缺乏注释。方法调用语句 58,有较多的方法调用,但每个方法内部语句少,大量的小方法调用。最深块深度 4,平均块深度 1.66,代码块的嵌套层次不深,结构清晰。

总结

缺少代码注释,可能导致代码可读性降低,设计的类众多,要注意单一职责。
有了之前电梯题目的经验,这次的算法显得非常简单,并且接触面向对象有一定时间,对于类设计也有一定的了解,整体题目写下来还是比较顺畅,没有遇到解决不了的问题,主要问题就是输入格式的问题,因为存在大量字符串和数字的输入,很容易导致输入的内容数据不匹配的错误报错,总结经验:每次获取double后要获取字符串的话,应该加一个nextLine(),用于吸收输入的回车。

踩坑心得


错误点:费率设计错误,导致我一直检查代码逻辑问题,单步调试很久,没有发现存在逻辑问题,最后通过数据计算,发现是费率设置出现了问题,这就能解释为什么只有部分正确了。希望以后写代码时避免这种低级错误。

第二次航空货运管理系统代码分析

题目分析

对上一次的航空货运管理系统进行迭代升级,主体没有什么太大变化,主要是引入了抽象类和接口,对乘客进行抽象,对不同乘客进行差异化处理,对货物进行抽象,对不同的货物类型进行差异化处理。题目要求按照如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。然后分别生成订单信息报表及货物明细报表,如果订单中货物重量超过航班剩余载重量,程序输出报错信息并且终止。
要满足面向对象设计原则:单一职责原则(20%)、里氏代换原则(20%)、开闭原则(20%)、合成复用原则(20%)、依赖倒转原则(20%)。

附上我的源码和源码分析

1.类图

1.Main类

新增 customerType 和 goodsType 输入,动态创建客户和货物对象。
支付选择:根据输入调用不同支付方式(WeChat/Alipay/Cash)。
根据客户类型创建 Individual 或 Corporate 对象。
根据货物类型创建 Normal/Expedite/Dangerous 对象。
计算运费时,同时考虑货物类型费率和客户折扣。

2.Customer 类(抽象类)

作用:抽象客户父类,支持客户子类不同的折扣。
改动与扩展:
新增抽象方法 getDiscount(),实现多态。
子类:
Individual(个人客户):默认折扣 0.9。
Corporate(企业客户):默认折扣 0.8。
Customer2:通过继承实现不同定价,提升灵活性。

3.Goods 类(抽象类)

作用:抽象货物父类,支持货物子类差异化,实现不同费率。
改动与扩展:
新增抽象方法 getType(),强制子类声明货物类型。
子类:
Normal(普通货物):基础费率。
Expedite(加急货物):更高费率。
Dangerous(危险品):最高费率。
作用:通过多态实现不同货物类型的运费计算,支持不同的业务规则。

4.Controller 类

作用:核心逻辑增强,支持客户折扣与货物类型不同计算。
关键改动:
calculateRate 方法:
根据货物类型动态调整费率。
结合客户折扣计算最终运费。
Show2 方法:输出时显示原始运费。
作用:
货物类型与客户类型共同影响总价,符合系统要求。

5.Payment 类及其子类

新增功能:
Cash 类:新增现金支付方式,扩展支付选项。
作用:支付方式更全面,支持微信、支付宝、现金三种选择。

2.代码分析

1.源码
点击查看代码
import java.util.*;

abstract class Customer{
    private String id;
    private String name;
    private String phone;
    private String address;
    private double goodNum;

    public Customer() {

    }
    public Customer(String id, String name, String phone, String address, double goodNum) {
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.address = address;
        this.goodNum = goodNum;
    }
    public Customer(String name, String phone, String address) {
        this.name = name;
        this.phone = phone;
        this.address = address;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public double getGoodNum() {
        return goodNum;
    }
    public void setGoodNum(double goodNum) {
        this.goodNum = goodNum;
    }
    abstract double getDiscount();
}
class Customer2 extends Customer{
    public Customer2() {

    }
    public Customer2(String name, String phone, String address) {
        super(name, phone, address);
    }
    @Override
    public double getDiscount() {
        return 0;
    }
}
class Individual extends Customer{
    private double discount;
    public Individual() {

    }
    public Individual(String id, String name, String phone, String address, double goodNum) {
        super(id, name, phone, address, goodNum);
        this.discount=0.9;
    }
    @Override
    public double getDiscount() {
        return discount;
    }
}
class Corporate extends Customer{
    private double discount;
    public Corporate() {

    }
    public Corporate(String id, String name, String phone, String address, double goodNum) {
        super(id, name, phone, address, goodNum);
        this.discount=0.8;
    }
    @Override
    public double getDiscount() {
        return discount;
    }
}
abstract class Goods{
    private String name;
    private double width;
    private double length;
    private double height;
    private double weight;
    private double volume=0;
    private double rate=0;
    private double price=0;
    private double W;//计费重量
    private String type;

    public Goods() {
        super();
    }
    public void SetW(double W){
        this.W=W;
    }
    public double GetW(){
        return this.W;
    }
    public Goods(String name, double width, double length, double height, double weight) {
        this.name = name;
        this.width = width;
        this.length = length;
        this.height = height;
        this.weight = weight;
    }
    public void SetPrice(double price){
        this.price=price;
    }
    public double GetPrice(){
        return this.price;
    }
    public void SetRate(double rate){
        this.rate=rate;
    }
    public double GetRate(){
        return this.rate;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getWidth() {
        return width;
    }
    public void setWidth(double width) {
        this.width = width;
    }
    public double getLength() {
        return length;
    }
    public void setLength(double length) {
        this.length = length;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    public double getVolume() {
        return width * length * height;
    }
    abstract String getType();
}
class Normal extends Goods{
    private String type = "Normal";
    Normal() {
        super();
    }
    public Normal(String name, double width, double length, double height, double weight) {
        super(name, width, length, height, weight);
    }
    @Override
    public String getType() {
        return type;
    }
}
class Expedite extends Goods {
    private String type = "Expedite";

    Expedite() {
        super();
    }

    public Expedite(String name, double width, double length, double height, double weight) {
        super(name, width, length, height, weight);
    }

    @Override
    public String getType() {
        return type;
    }
}

class Dangerous extends Goods {
    private String type = "Dangerous";

    Dangerous() {
        super();
    }

    public Dangerous(String name, double width, double length, double height, double weight) {
        super(name, width, length, height, weight);
    }

    @Override
    public String getType() {
        return type;
    }
}

class Plane {
    private String id;
    private String place1;
    private String place2;
    private String time;
    private double maxWeight;

    public Plane() {

    }

    public Plane(String id, String place1, String place2, String time, double maxWeight) {
        this.id = id;
        this.place1 = place1;
        this.place2 = place2;
        this.time = time;
        this.maxWeight = maxWeight;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPlace1() {
        return place1;
    }

    public void setPlace1(String place1) {
        this.place1 = place1;
    }

    public String getPlace2() {
        return place2;
    }

    public void setPlace2(String place2) {
        this.place2 = place2;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public double getMaxWeight() {
        return maxWeight;
    }

    public void setMaxWeight(double maxWeight) {
        this.maxWeight = maxWeight;
    }
}

class Order {
    private String id;
    private String time;
    private Customer customer1;
    private Customer customer2;
    private LinkedList<Goods> goodsList = new LinkedList<>();
    private double totalPrice = 0;

    public Order() {

    }

    public Order(String id, String time, Customer customer1, Customer customer2, LinkedList<Goods> goodsList) {
        this.id = id;
        this.time = time;
        this.customer1 = customer1;
        this.customer2 = customer2;
        this.goodsList = goodsList;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public Customer getCustomer1() {
        return customer1;
    }

    public void setCustomer1(Customer customer1) {
        this.customer1 = customer1;
    }

    public Customer getCustomer2() {
        return customer2;
    }

    public void setCustomer2(Customer customer2) {
        this.customer2 = customer2;
    }

    public void setGoodsList(LinkedList<Goods> goodsList) {
        this.goodsList = goodsList;
    }

    public LinkedList<Goods> getGoodsList() {
        return goodsList;
    }

    public void addGoods(Goods goods) {
        goodsList.add(goods);
    }
}

abstract class Payment {
    private String option;

    public Payment() {

    }

    public Payment(String option) {
        this.option = option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    public abstract void getOption();
}

class WeChat extends Payment {
    WeChat() {
        super();
    }

    @Override
    public void getOption() {
        System.out.print("微信支付金额:");
    }
}

class Alipay extends Payment {
    Alipay() {
        super();
    }

    @Override
    public void getOption() {
        System.out.print("支付宝支付金额:");
    }
}

class Cash extends Payment {
    Cash() {
        super();
    }

    @Override
    public void getOption() {
        System.out.print("现金支付金额:");
    }
}

class Controller {
    private Plane plane;
    private Order order;
    private Customer customer1;
    private Customer customer2;
    private Customer customer;
    private LinkedList<Goods> goodsList = new LinkedList<>();

    double totalWeight = 0;

    public Controller() {

    }

    public Controller(Plane plane, Order order, Customer customer1, Customer customer2, Customer customer) {
        this.plane = plane;
        this.order = order;
        this.customer1 = customer1;
        this.customer2 = customer2;
        this.goodsList = order.getGoodsList();
        this.customer = customer;
    }

    public void calculateRate(Goods good, Customer customer) {
        String type = good.getType();
        double discount = customer.getDiscount();
        switch (type) {
            case "Normal":
                for (int i = 0; i < goodsList.size(); i++) {
                    double w1 = goodsList.get(i).getWeight();
                    double w2 = 1.0 * goodsList.get(i).getVolume() / 6000;
                    if (w1 < w2) {
                        w1 = w2;
                    }
                    goodsList.get(i).SetW(w1);
                    if (w1 < 20) {
                        goodsList.get(i).SetRate(35);
                    } else if (w1 >= 20 && w1 < 50) {
                        goodsList.get(i).SetRate(30);
                    } else if (w1 >= 50 && w1 < 100) {
                        goodsList.get(i).SetRate(25);
                    } else if (w1 >= 100) {
                        goodsList.get(i).SetRate(15);
                    }
                    goodsList.get(i).SetPrice(w1 * goodsList.get(i).GetRate() * discount);
                    totalWeight += w1;
                }
                break;
            case "Dangerous":
                for (int i = 0; i < goodsList.size(); i++) {
                    double w1 = goodsList.get(i).getWeight();
                    double w2 = 1.0 * goodsList.get(i).getVolume() / 6000;
                    if (w1 < w2) {
                        w1 = w2;
                    }
                    goodsList.get(i).SetW(w1);
                    if (w1 < 20) {
                        goodsList.get(i).SetRate(80);
                    } else if (w1 >= 20 && w1 < 50) {
                        goodsList.get(i).SetRate(50);
                    } else if (w1 >= 50 && w1 < 100) {
                        goodsList.get(i).SetRate(30);
                    } else if (w1 >= 100) {
                        goodsList.get(i).SetRate(20);
                    }
                    goodsList.get(i).SetPrice(w1 * goodsList.get(i).GetRate() * discount);
                    totalWeight += w1;
                }
                break;
            case "Expedite":
                for (int i = 0; i < goodsList.size(); i++) {
                    double w1 = goodsList.get(i).getWeight();
                    double w2 = 1.0 * goodsList.get(i).getVolume() / 6000;
                    if (w1 < w2) {
                        w1 = w2;
                    }
                    goodsList.get(i).SetW(w1);
                    if (w1 < 20) {
                        goodsList.get(i).SetRate(60);
                    } else if (w1 >= 20 && w1 < 50) {
                        goodsList.get(i).SetRate(50);
                    } else if (w1 >= 50 && w1 < 100) {
                        goodsList.get(i).SetRate(40);
                    } else if (w1 >= 100) {
                        goodsList.get(i).SetRate(30);
                    }
                    goodsList.get(i).SetPrice(w1 * goodsList.get(i).GetRate() * discount);
                    totalWeight += w1;
                }
                break;
        }
    }

    public double getTotalPrice() {
        double totalPrice = 0;
        for (int i = 0; i < goodsList.size(); i++) {
            totalPrice += goodsList.get(i).GetPrice();
        }
        return totalPrice;
    }

    public boolean Check() {
        if (totalWeight > plane.getMaxWeight()) {
            return false;
        }
        return true;
    }

    public void Show1() {
        System.out.println("客户:" + customer.getName() + "(" + customer.getPhone() + ")订单信息如下:");
        System.out.println("-----------------------------------------");
        System.out.println("航班号:" + plane.getId());
        System.out.println("订单号:" + order.getId());
        System.out.println("订单日期:" + order.getTime());
        System.out.println("发件人姓名:" + order.getCustomer1().getName());
        System.out.println("发件人电话:" + order.getCustomer1().getPhone());
        System.out.println("发件人地址:" + order.getCustomer1().getAddress());
        System.out.println("收件人姓名:" + order.getCustomer2().getName());
        System.out.println("收件人电话:" + order.getCustomer2().getPhone());
        System.out.println("收件人地址:" + order.getCustomer2().getAddress());
        System.out.println("订单总重量(kg):" + totalWeight);
    }

    public void Show2() {

        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.printf("明细编号\t货物名称\t计费重量\t计费费率\t应交运费\n");
        for (int i = 0; i < goodsList.size(); i++) {
            System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f",
                    i + 1,
                    goodsList.get(i).getName(),
                    goodsList.get(i).GetW(),
                    goodsList.get(i).GetRate(),
                    goodsList.get(i).GetPrice()/ customer.getDiscount()
            );
            if (i != goodsList.size() - 1) {
                System.out.printf("\n");
            }
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String customerType = "";
        String customerId = "";
        String customerName = "";
        String customerPhone = "";
        String customerAddress = "";
        double customerGoodsNum = 0;
        String goodsType = "";
        customerType = scanner.nextLine();
        customerId = scanner.nextLine();
        customerName = scanner.nextLine();
        customerPhone = scanner.nextLine();
        customerAddress = scanner.nextLine();;
        goodsType = scanner.nextLine();
        customerGoodsNum = scanner.nextDouble();
        scanner.nextLine();
        LinkedList<Goods> goodsList = new LinkedList<>();
        Customer customer = null;
        if(customerType.equals("Individual")){
            customer = new Individual(customerId, customerName, customerPhone, customerAddress, customerGoodsNum);
        }else if(customerType.equals("Corporate")){
            customer = new Corporate(customerId, customerName, customerPhone, customerAddress, customerGoodsNum);
        }
        for(int i = 0; i < customerGoodsNum; i++){
            String goodsName = "";
            double goodsWidth = 0;
            double goodsLength = 0;
            double goodsHeight = 0;
            double goodsWeight = 0;
            scanner.nextLine();
            goodsName = scanner.nextLine();
            goodsWidth = scanner.nextDouble();
            goodsLength = scanner.nextDouble();
            goodsHeight = scanner.nextDouble();
            goodsWeight = scanner.nextDouble();
            scanner.nextLine();
            if(goodsType.equals("Normal")){
                Goods goods = new Normal(goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
                goodsList.add(goods);
            }
            else if(goodsType.equals("Expedite")) {
                Goods goods = new Expedite(goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
                goodsList.add(goods);
            }
            else if(goodsType.equals("Dangerous")) {
                Goods goods = new Dangerous(goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
                goodsList.add(goods);
            }
        }
        String PlaneId = "";
        String place1 = "";
        String place2 = "";
        String time = "";
        double maxWeight = 0;
        PlaneId = scanner.nextLine();
        place1 = scanner.nextLine();
        place2 = scanner.nextLine();
        time = scanner.nextLine();
        maxWeight = scanner.nextDouble();
        scanner.nextLine();
        Plane plane = new Plane(PlaneId, place1, place2, time, maxWeight);
        String orderId = "";
        String orderTime = "";
        String orderAddress1 = "";
        String orderName1 = "";
        String orderPhone1 = "";
        String orderAddress2 = "";
        String orderName2 = "";
        String orderPhone2 = "";
        orderId = scanner.nextLine();
        orderTime = scanner.nextLine();
        orderAddress1 = scanner.nextLine();
        orderName1 = scanner.nextLine();
        orderPhone1 = scanner.nextLine();
        orderAddress2 = scanner.nextLine();
        orderName2 = scanner.nextLine();
        orderPhone2 = scanner.nextLine();
        String paymentOption = "";
        paymentOption = scanner.nextLine();

        Customer2 customer1 = new Customer2(orderName1, orderPhone1, orderAddress1);
        Customer2 customer2 = new Customer2(orderName2, orderPhone2, orderAddress2);
        Order order = new Order(orderId, orderTime, customer1, customer2, goodsList);
        Controller controller = new Controller(plane, order, customer1, customer2,customer);
        controller.calculateRate(goodsList.get(0), customer );
        if(!controller.Check()){
            System.out.println("The flight with flight number:"+plane.getId()+" has exceeded its load capacity and cannot carry the order.");
            return ;
        }
        controller.Show1();
        if(paymentOption.equals("Wechat")){
            Payment payment = new WeChat();
            payment.getOption();
        }else if(paymentOption.equals("ALiPay")){
            Payment payment = new Alipay();
            payment.getOption();
        }else if(paymentOption.equals("Cash")){
            Payment payment = new Cash();
            payment.getOption();
        }
        System.out.println(controller.getTotalPrice());
        System.out.println("");
        controller.Show2();
    }
}

2.SourceMonitor代码分析:


3.数据分析

行数(Lines)643
语句数(Statements)321
分支语句百分比(Percent Branch Statements)8.4
方法调用语句(Method Call Statements)63
注释行百分比(Percent Lines with Comments)0.2
类和接口数量(Classes and Interfaces)13
每个类的方法数(Methods per Class)6.69
每个方法的平均语句数(Average Statements per Method)1.97
最复杂方法的行号(Line Number of Most Complex Method)418
方法名是 Controller.calculateRate ()
最大复杂度(Maximum Complexity)29
最深块的行号(Line Number of Deepest Block)427
最大块深度(Maximum Block Depth)6
平均块深度(Average Block Depth)2.01
平均复杂度(Average Complexity)1.35

4.分析

13 个类,平均 6.69 个方法,类职责分布较均匀。但平均语句数 / 方法低,说明大量简单方法(如 getter/setter),没有使用,需合并无意义方法。注释(0.2%):几乎无文档说明,导致代码可理解性差。最大复杂度(29,Controller.calculateRate()):逻辑嵌套,条件过多。
平均复杂度(1.35):整体低。最大深度(6):说明部分逻辑较复杂需要简化,提升可读性。
平均深度(2.01):分支结构少。

5.总结

代码存在三个问题,一个是没有任何注释还有就是局部复杂度过高 ,以及方法过多设计了,需通过注释补充、重新写算法、多余方法简化三步提升,提高代码可读性。根据数据分析,这次代码平均深度和上一次差不太多,但是最高复杂度高很大很大,最大深度也高很多,说明逻辑方面提升了很多,因为这次增加了不同客户类型和不同货物类型,导致收费的算法方法添加了很多逻辑,并且没有很好的进行处理。

6.踩坑心得

1.注意计费所采取的实际重量,



我的处理方式比较笨拙,我新加了一个私有属性,计费重量,通过比较较大值,通过set方法设置,以便后续进行的计费操作。

2.格式错误导致的错误

题目要求的间隔是制表符(\t)而不是空格,多次用空格当制表符导致格式错误。

3.费率的设置问题

给出的实验要求那个费率和货物类型有一个顺序是反的,如果不仔细看,而是顺序的按照图上的数据是一直都不对的。

4.创建不同货物对象问题

可以用switch case来根据用户输入的不同情况进行创建不同的对象。

其中,易错点就是,将货物类型直接用字符串区别,因为在用户输入之前,是无法得知输入的货物类型是什么样的,所以应该设计三种不同的对象类。

5.应交费用和支付总额是对不上的

应交费用是没有打折之前的费用,而支付总额是打折之后的金额,这里迷惑了好久,最后还是询问了其他同学才得以解决。

改进建议

总结

通过这次题目集学到的内容

面向对象基本原则

1.单一职责原则(SRP)
Customer、Goods、Plane、Payment 等类的职责清晰,分别管理客户、货物、航班和支付逻辑。
Controller 类负责协调业务逻辑(计算、校验、展示))。
使得整个代码结构清晰,职责分离开来也更好的进行修改和扩展。
2.开封原则(OCP)
通过抽象类(如 Customer、Goods、Payment)定义接口,子类(如 Individual、Corporate、Normal、WeChat)扩展功能。新增类型(新客户类型、新支付方式)无需修改现有代码。
Controller 的 calculateRate 方法根据货物类型动态计算费率,通过多态减少条件判断。
使得代码具有很强的扩展性,体现在对修改关闭对扩展开发,需要扩展功能是只需要再添加相应代码即可,不需要再而外修改之前写过的代码。
3.里氏替换原则(LSP)
所有子类(如 Individual 继承 Customer)完全兼容父类行为,重写的方法(如 getDiscount())保持逻辑一致性。
4.依赖倒置原则(DIP)
Controller 依赖于抽象的 Customer 和 Goods,而非具体实现,降低了各个区域的耦合度。
5.多态与继承
客户类型(个人/企业)和货物类型(普通/加急/危险品)通过继承实现差异化逻辑,可以避免重复造轮子。

需进一步学习的方面

1.代码复用性与效率待优化重复逻辑的冗余实例化:运费计算逻辑在 calculateRate 方法中重复遍历货物列表,且每次计算均重新初始化变量,较为复杂。
2.当前代码未对关键输入如客户信息、货物尺寸、航班载重进行有效性校验,可能引发空指针等问题。
3.当前对开闭原则的应用停留在基础接口与继承的实现上。通过抽象类(如 Goods、Customer)和子类扩展了功能,但在复杂场景中,仍依赖 switch-case 或条件分支(如 calculateRate 方法),未充分抽象为独立类。

改进与建议

1.对于类设计存在设计慢等缺陷,需要多实际,多设计来提升自己的类设计能力。在编写代码过程中的低级错误也存在,需要多注意。
2.对于一个工程量比较大的题目,存在不知道从哪里下手等问题,需要多编码积累经验
3.面向对象的很多基本概念,只知道如何使用而不知道它的具体含义和更多的使用场景,需要在线上线下课上提高自己的听课效率。
4.存在很多方法不知道如何使用,JAVA中容器类,String类提供了很多方便的方法,需要多多使用以掌握,可以大大提高自己的编码效率。

posted @ 2025-05-25 19:59  翻斗花园突击手胡图图  阅读(39)  评论(0)    收藏  举报