第二次博客作业——航空货运管理系统
第二次Blog作业——航空货运管理系统
一、前言
这一个月以来,我们迎来了第二次的迭代作业——航空货运管理系统。有了第一次的迭代经验,这次的迭代相较于第一次来说,更加轻松、简单。与此同时,航空货运管理系统所带来的一些挑战也给了我进步,下面我将对这次的迭代过程加以分析。
二、设计与分析
1、第一次迭代设计与分析
(1)代码展示
第一次迭代
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        String customerNumber = input.nextLine(); //客户编号
        String customerName = input.nextLine();//客户姓名
        String customerPhoneNumber = input.nextLine();//客户电话
        String customerAddress = input.nextLine();//客户地址
        Customer customer = new Customer(customerName, customerPhoneNumber, customerAddress);
        int goodsNum = input.nextInt();//运送货物数量
        input.nextLine();// 消耗换行符
        //货物信息
        ArrayList<Goods> list = new ArrayList<>();
        for (int i = 0; i < goodsNum; i++) {
            String goodsNumber = input.nextLine(); //货物编号
            String goodsName = input.nextLine();	//货物名称
            //货物长宽高
            int width = input.nextInt();
            input.nextLine();
            int length = input.nextInt();
            input.nextLine();
            int height = input.nextInt();
            input.nextLine();
            //货物实际重量
            int grossWeight = input.nextInt();
            input.nextLine();
            list.add(new Goods(goodsNumber, goodsName, length, width, height, grossWeight));
        }
        //航班信息
        String flightNumber = input.nextLine(); //航班号
        String startAirport = input.nextLine(); //起飞机场
        String endAirport = input.nextLine();	//降落机场
        String flightDate = input.nextLine();	//航班日期
        int maxload = input.nextInt();			//最大载重
        Flight flight = new Flight(flightNumber, startAirport, endAirport, flightDate, maxload);
        input.nextLine();
        String orderNumber = input.nextLine(); //订单编号
        String orderDate = input.nextLine();	//订单日期
        //发件人信息
        String senderAddress = input.nextLine();
        String senderName = input.nextLine();
        String senderPhoneNumber = input.nextLine();
        Sender sender = new Sender(senderName, senderPhoneNumber, senderAddress);
        //收件人信息
        String recevierAddress = input.nextLine();
        String recevierName = input.nextLine();
        String recevierPhoneNumber = input.nextLine();
        Recevier recevier = new Recevier(recevierName, recevierPhoneNumber, recevierAddress);
        //邮寄信息
        PostMessage postMessage = new PostMessage(sender, recevier, flightNumber, orderDate, orderNumber);
        //支付方式
        Pay pay = new WechatPay();
        //客户信息
        CustomerInfo customerInfo = new CustomerInfo(customer, list, postMessage, pay);
        //航空公司处理
        Airline airline = new Airline(customerNumber,customerInfo,flight);
        input.close();
        if(airline.isValid()) {
            airline.showInfo();
        } else {
            System.out.println("The flight with flight number:" + flight.getFlightNumber() + 
                    " has exceeded its load capacity and cannot carry the order.");
        }
    }
}
class Airline {
    private String customerNumber;
    private CustomerInfo customerInfo;
    private Flight flight;
    private double sumWeight;
    private double sumCost;
    public Airline(String customerNumber, CustomerInfo customerInfo, Flight flight) {
        super();
        this.customerNumber = customerNumber;
        this.customerInfo = customerInfo;
        this.flight = flight;
    }
    public Airline() {
        super();
        // TODO Auto-generated constructor stub
    }
    public String getCustomerNumber() {
        return customerNumber;
    }
    public void setCustomerNumber(String customerNumber) {
        this.customerNumber = customerNumber;
    }
    public CustomerInfo getCustomerInfo() {
        return customerInfo;
    }
    public void setCustomerInfo(CustomerInfo customerInfo) {
        this.customerInfo = customerInfo;
    }
    public Flight getFlight() {
        return flight;
    }
    public void setFlight(Flight flight) {
        this.flight = flight;
    }
    public boolean isValid() {
        Iterator<Goods> itr = customerInfo.getList().iterator();
        sumWeight = 0;
        while(itr.hasNext()) {
            Goods goods = itr.next();
            this.sumWeight += goods.getCount().getActualWeight();
            this.sumCost += goods.getCount().getCost();
        }
        return sumWeight < flight.getMaxload();
    }
    public void showInfo() {
        System.out.printf("客户:%s(%s)订单信息如下:\n",customerInfo.getCustomer().getName(),
                customerInfo.getCustomer().getPhoneNumber());
        System.out.println("-----------------------------------------");
        System.out.println("航班号:" + flight.getFlightNumber());
        System.out.println("订单号:" + customerInfo.getPostMessage().getOrderNumber());
        System.out.println("订单日期:" + customerInfo.getPostMessage().getOrderDate());
        System.out.println("发件人姓名:" + customerInfo.getPostMessage().getSender().getName());
        System.out.println("发件人电话:" + customerInfo.getPostMessage().getSender().getPhoneNumber());
        System.out.println("发件人地址:" + customerInfo.getPostMessage().getSender().getAddress());
        System.out.println("收件人姓名:" + customerInfo.getPostMessage().getRecivier().getName());
        System.out.println("收件人电话:" + customerInfo.getPostMessage().getRecivier().getPhoneNumber());
        System.out.println("收件人地址:" + customerInfo.getPostMessage().getRecivier().getAddress());
        System.out.println("订单总重量(kg):" + this.sumWeight);
        System.out.println(customerInfo.getPay().Show() + String.format("%.1f", this.sumCost));
        System.out.println("");
        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
        Iterator<Goods> itr = customerInfo.getList().iterator();
        for(int i = 1; itr.hasNext(); i++) {
            Goods goods = itr.next();
            System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",i,goods.getName(),
                    goods.getCount().getActualWeight(),goods.getCount().getRate(),
                    goods.getCount().getCost());
        }
    }
}
class Flight {
    private String flightNumber;
    private String startAirport;
    private String endAirport;
    private String flightDate;
    private int maxload;
    public Flight(String flightNumber, String startAirport, String endAirport, String flightDate, int maxload) {
        super();
        this.flightNumber = flightNumber;
        this.startAirport = startAirport;
        this.endAirport = endAirport;
        this.flightDate = flightDate;
        this.maxload = maxload;
    }
    public Flight() {
        super();
        // TODO Auto-generated constructor stub
    }
    public String getFlightNumber() {
        return flightNumber;
    }
    public void setFlightNumber(String flightNumber) {
        this.flightNumber = flightNumber;
    }
    public String getStartAirport() {
        return startAirport;
    }
    public void setStartAirport(String startAirport) {
        this.startAirport = startAirport;
    }
    public String getEndAirport() {
        return endAirport;
    }
    public void setEndAirport(String endAirport) {
        this.endAirport = endAirport;
    }
    public String getFlightDate() {
        return flightDate;
    }
    public void setFlightDate(String flightDate) {
        this.flightDate = flightDate;
    }
    public int getMaxload() {
        return maxload;
    }
    public void setMaxload(int maxload) {
        this.maxload = maxload;
    }
}
class CustomerInfo {
    private Customer customer;
    private ArrayList<Goods> list;
    private PostMessage postMessage;
    private Pay pay;
    public CustomerInfo(Customer customer, ArrayList<Goods> list, PostMessage postMessage, Pay pay) {
        super();
        this.customer = customer;
        this.list = list;
        this.postMessage = postMessage;
        this.pay = pay;
    }
    public CustomerInfo() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public ArrayList<Goods> getList() {
        return list;
    }
    public void setList(ArrayList<Goods> list) {
        this.list = list;
    }
    public PostMessage getPostMessage() {
        return postMessage;
    }
    public void setPostMessage(PostMessage postMessage) {
        this.postMessage = postMessage;
    }
    public Pay getPay() {
        return pay;
    }
    public void setPay(Pay pay) {
        this.pay = pay;
    }
}
class Person {
    protected String name;
    protected String phoneNumber;
    protected String address;
    public Person(String name, String phoneNumber, String address) {
        super();
        this.name = name;
        this.phoneNumber = phoneNumber;
        this.address = address;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhoneNumber() {
        return phoneNumber;
    }
    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}
class Customer extends Person {
    public Customer(String name, String phoneNumber, String address) {
        super(name, phoneNumber, address);
    }
    public Customer() {
        super();
        // TODO Auto-generated constructor stub
    }
}
class Sender extends Person {
    public Sender(String name, String phoneNumber, String address) {
        super(name, phoneNumber, address);
    }
    public Sender() {
        super();
        // TODO Auto-generated constructor stub
    }
}
class Recevier extends Person {
    public Recevier(String name, String phoneNumber, String address) {
        super(name, phoneNumber, address);
    }
    public Recevier() {
        super();
        // TODO Auto-generated constructor stub
    }
}
class PostMessage {
    private Sender sender;
    private Recevier recivier;
    private String flightNumber;
    private String orderDate;
    private String orderNumber;
    public PostMessage(Sender sender, Recevier recevier, String flightNumber, String orderDate, String orderNumber) {
        super();
        this.sender = sender;
        this.recivier = recevier;
        this.flightNumber = flightNumber;
        this.orderDate = orderDate;
        this.orderNumber = orderNumber;
    }
    public PostMessage() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Sender getSender() {
        return sender;
    }
    public void setSender(Sender sender) {
        this.sender = sender;
    }
    public Recevier getRecivier() {
        return recivier;
    }
    public void setRecevier(Recevier recivier) {
        this.recivier = recivier;
    }
    public String getFlightNumber() {
        return flightNumber;
    }
    public void setFlightNumber(String flightNumber) {
        this.flightNumber = flightNumber;
    }
    public String getOrderDate() {
        return orderDate;
    }
    public void setOrderDate(String orderDate) {
        this.orderDate = orderDate;
    }
    public String getOrderNumber() {
        return orderNumber;
    }
    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }
}
abstract class Pay {
    public abstract String Show();
}
class WechatPay extends Pay {
    @Override
    public String Show() {
        return "微信支付金额:";
    }
}
class AliPay extends Pay {
    @Override
    public String Show() {
        return "支付宝支付金额:";
    }
}
class Count {
    private double grossWeight;
    private double volumeWeight;
    public Count() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Count(double grossWeight, double volumeWeight) {
        super();
        this.grossWeight = grossWeight;
        this.volumeWeight = volumeWeight;
    }
    public double getActualWeight() {
        if (grossWeight < volumeWeight) {
            return this.volumeWeight;
        } else {
            return this.grossWeight;
        }
    }
    public double getRate() {
        double actualWeight = getActualWeight();
        double rate = 0;
        if (actualWeight < 20 && actualWeight >= 0) {
            rate = 35.0;
        } else if (actualWeight < 50) {
            rate = 30.0;
        } else if (actualWeight < 100) {
            rate = 25.0;
        } else if (actualWeight >= 100) {
            rate = 15.0;
        }
        return rate;
    }
    public double getCost() {
        return getActualWeight() * getRate();
    }
}
class Goods {
    private String goodsNumber;
    private String name;
    private double length;
    private double width;
    private double height;
    private double grossWeight;
    private double volumeWeight;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getLength() {
        return length;
    }
    public void setLength(double length) {
        this.length = length;
    }
    public double getWidth() {
        return width;
    }
    public void setWidth(double width) {
        this.width = width;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public double getGrossWeight() {
        return grossWeight;
    }
    public void setGrossWeight(double grossWeight) {
        this.grossWeight = grossWeight;
    }
    public String getGoodsNumber() {
        return goodsNumber;
    }
    public void setGoodsNumber(String goodsNumber) {
        this.goodsNumber = goodsNumber;
    }
    private Count count;
    public Count getCount() {
        return count;
    }
    public void setCount(Count count) {
        this.count = count;
    }
    public Goods(String goodsNumber,String name, double length, double width, double height, double grossWeight) {
        super();
        this.goodsNumber = goodsNumber;
        this.name = name;
        this.length = length;
        this.width = width;
        this.height = height;
        this.grossWeight = grossWeight;
        volumeWeight = getVolumeWeight();
        count = new Count(this.grossWeight, this.volumeWeight);
    }
    private double getVolumeWeight() {
        return  ((this.length * this.width * this.height) / 6000);
    }
}(2)类间关系分析及类图
- Main类:用于获取用户输入信息。依赖于Airline类。
- Person类及其子类:Customer(客户类)、Sender(发件人)、Recevier(收件人)继承自父类Person。
- Pay类及其子类:WechatPay类(微信支付)和AliPay类(支付宝支付)继承自抽象类Pay。
- Airline类:Airline类(航空公司)包含CustomerInfo类(客户信息)和Flight类(航班),形成组合关系。
- customerInfo类:CustomerInfo包含Customer、PostMessage(邮寄信息)、Pay,形成组合关系。CustomerInfo包含ArrayList<Goods>货物列表,形成聚合关系。
- postMessage类:PostMessage包含Sender和Recevier,形成组合关系。
- Goods类:Goods(货物)包含Count(计费信息),形成组合关系。同时Goods又需要Count类的方法,形成了依赖关系。

(3)SourceMoniter分析代码:

分析详情
 Metrics Details For File 'Main.java'
--------------------------------------------------------------------------------------------
Parameter				Value
=========				=====
Project Directory			C:\Users\25734\eclipse-workspace\SouseMoniter\src\test1\
Project Name				分析结果4
Checkpoint Name				Baseline
File Name				Main.java
Lines					556
Statements				173
Percent Branch Statements		5.8
Method Call Statements			59
Percent Lines with Comments		4.7
Classes and Interfaces			5
Methods per Class			6.60
Average Statements per Method		3.48
Line Number of Most Complex Method	448
Name of Most Complex Method		Count.getRate()
Maximum Complexity			6
Line Number of Deepest Block		20
Maximum Block Depth			3
Average Block Depth			1.73
Average Complexity			1.33
--------------------------------------------------------------------------------------------
Most Complex Methods in 5 Class(es):	Complexity, Statements, Max Depth, Calls
Airline.Airline()			1, 1, 2, 1
Airline.Airline()			1, 4, 2, 1
Airline.getCustomerInfo()		1, 1, 2, 0
Airline.getCustomerNumber()		1, 1, 2, 0
Airline.getFlight()			1, 1, 2, 0
Airline.isValid()			2, 7, 3, 6
Airline.setCustomerInfo()		1, 1, 2, 0
Airline.setCustomerNumber()		1, 1, 2, 0
Airline.setFlight()			1, 1, 2, 0
Airline.showInfo()			1, 11, 2, 13
AliPay.Show()				1, 1, 2, 0
Count.Count()				1, 3, 2, 1
Count.Count()				1, 1, 2, 1
Count.getActualWeight()			3, 4, 3, 0
Count.getCost()				1, 1, 2, 2
Count.getRate()				6, 11, 3, 1
Goods.getCount()			1, 1, 2, 0
Goods.getGoodsNumber()			1, 1, 2, 0
Goods.getGrossWeight()			1, 1, 2, 0
Goods.getHeight()			1, 1, 2, 0
Goods.getLength()			1, 1, 2, 0
Goods.getName()				1, 1, 2, 0
Goods.getVolumeWeight()			1, 1, 2, 0
Goods.getWidth()			1, 1, 2, 0
Goods.Goods()				1, 9, 2, 2
Goods.setCount()			1, 1, 2, 0
Goods.setGoodsNumber()			1, 1, 2, 0
Goods.setGrossWeight()			1, 1, 2, 0
Goods.setHeight()			1, 1, 2, 0
Goods.setLength()			1, 1, 2, 0
Goods.setName()				1, 1, 2, 0
Goods.setWidth()			1, 1, 2, 0
Main.main()				4, 41, 3, 31
--------------------------------------------------------------------------------------------
Block Depth				Statements
0					9
1					49
2					94
3					21
4					0
5					0
6					0
7					0
8					0
9+					0
--------------------------------------------------------------------------------------------一、基本信息
- 代码规模
- Lines:556 行。
- Statements:173 条语句。
 
二、代码结构指标
- 控制流相关
- Percent Branch Statements:5.8% ,即分支语句占比,说明代码中条件判断(如if - else、switch )等逻辑占整体语句比例较低,代码执行路径相对较直接。
- Method Call Statements:59 条,反映方法调用的频繁程度,较多的方法调用意味着代码模块化程度尚可,通过方法调用来组织功能逻辑。
 
- 注释情况
- Percent Lines with Comments:4.7% ,注释行占比很低,意味着代码中注释较少,可能会降低代码可读性和可维护性,后续理解和修改代码难度增加。
 
- 类与方法统计
- Classes and Interfaces:5 个,代表文件中定义的类和接口数量。
- Methods per Class:平均每个类 6.60 个方法,表明类的功能相对丰富,但也可能存在类的职责不够单一的情况。
- Average Statements per Method:平均每个方法 3.48 条语句,说明方法的平均规模较小,方法逻辑相对简洁。
 
三、复杂度指标
- 最复杂方法
- Line Number of Most Complex Method:448 行,Name of Most Complex Method 为 Count.getRate() ,Maximum Complexity 是 6 。说明该方法在代码中的位置以及它的复杂程度较高,可能存在较多的条件判断、循环嵌套或复杂的业务逻辑。
 
- 代码块深度
- Line Number of Deepest Block:20 行,Maximum Block Depth:3 ,Average Block Depth:1.73 ,反映代码中代码块的嵌套深度情况,最深块深度为 3 ,平均深度 1.73 ,说明整体代码块嵌套不算太深,但仍有一定复杂度。
 
- 平均复杂度
- Average Complexity:1.33 ,表示代码整体的平均复杂程度,数值较低说明大部分代码逻辑相对简单,但存在个别复杂方法拉高整体复杂度。
 
四、改进方向
- 补充注释以提升代码可读性;
- 对复杂方法(如Count.getRate() )进行重构,简化逻辑;
- 进一步优化代码结构,合理拆分方法和类,提升代码的可维护性和扩展性。
体会:这是航空货运管理的第一次迭代,我仿照之前汽车雨刷的Agent类做了一个Airline类(航空公司)用于处理航班与客户两者的消息并生成订单,这种处理方式满足了迪米特法则即最小知道原则,使得类与类间的耦合减小。对于Person类与Pay类,我做了抽象与继承,使得代码更加精简,同时满足了多态。
2、第二次迭代设计与分析
(1)代码展示
第二次迭代代码
 import java.util.Scanner;
import java.util.Iterator;
import java.util.ArrayList;
public class Main {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		String kindOfcustomer = input.nextLine();
		String customerNumber = input.nextLine(); //客户编号
		String customerName = input.nextLine();//客户姓名
		String customerPhoneNumber = input.nextLine();//客户电话
		String customerAddress = input.nextLine();//客户地址
		Customer customer;
		double discount = 0;
		if(kindOfcustomer.equals("Individual")) {
			customer = new CustomerOfIndividual(customerName, customerPhoneNumber, customerAddress);
			discount = 0.9;
		}else if(kindOfcustomer.equals("Corporate")) {
			customer = new CustomerOfCorporate(customerName, customerPhoneNumber, customerAddress);
			discount = 0.8;
		}else {
			input.close();
			return;
		}
		String kindOfGoods = input.nextLine();
		int goodsNum = input.nextInt();//运送货物数量
		input.nextLine();// 消耗换行符
		//货物信息
		ArrayList<Goods> list = new ArrayList<>();
		for (int i = 0; i < goodsNum; i++) {
			String goodsNumber = input.nextLine(); //货物编号
			String goodsName = input.nextLine();	//货物名称
			//货物长宽高
			int width = input.nextInt();
			input.nextLine();
			int length = input.nextInt();
			input.nextLine();
			int height = input.nextInt();
			input.nextLine();
			//货物实际重量
			int grossWeight = input.nextInt();
			input.nextLine();
			//list.add(new Goods(goodsNumber, goodsName, length, width, height, grossWeight));
			if(kindOfGoods.equals("Normal")) {
				list.add(new GoodsOfNormal(goodsNumber, goodsName, length, width, height, grossWeight));
			}else if(kindOfGoods.equals("Expedite")) {
				list.add(new GoodsOfExpedite(goodsNumber, goodsName, length, width, height, grossWeight));
			}else if(kindOfGoods.equals("Dangerous")) {
				list.add(new GoodsOfDangerous(goodsNumber, goodsName, length, width, height, grossWeight));
			}
		}
		//航班信息
		String flightNumber = input.nextLine(); //航班号
		String startAirport = input.nextLine(); //起飞机场
		String endAirport = input.nextLine();	//降落机场
		String flightDate = input.nextLine();	//航班日期
		int maxload = input.nextInt();			//最大载重
		Flight flight = new Flight(flightNumber, startAirport, endAirport, flightDate, maxload);
		input.nextLine();
		String orderNumber = input.nextLine(); //订单编号
		String orderDate = input.nextLine();	//订单日期
		//发件人信息
		String senderAddress = input.nextLine();
		String senderName = input.nextLine();
		String senderPhoneNumber = input.nextLine();
		Sender sender = new Sender(senderName, senderPhoneNumber, senderAddress);
		//收件人信息
		String recevierAddress = input.nextLine();
		String recevierName = input.nextLine();
		String recevierPhoneNumber = input.nextLine();
		Recevier recevier = new Recevier(recevierName, recevierPhoneNumber, recevierAddress);
		//邮寄信息
		PostMessage postMessage = new PostMessage(sender, recevier, flightNumber, orderDate, orderNumber);
		//支付方式
		String payment = input.nextLine();
		Pay pay;
		if(payment.equals("Wechat")) {
			pay = new WechatPay();
		}else if(payment.equals("ALiPay")) {
			pay = new ALiPay();
		}else if(payment.equals("Cash")) {
			pay = new Cash();
		}else {
			input.close();
			return;
		}
		//客户信息
		CustomerInfo customerInfo = new CustomerInfo(customer, list, postMessage, pay);
		//航空公司处理
		Airline airline = new Airline(customerNumber,customerInfo,flight,discount);
		input.close();
		if(airline.isValid()) {
			airline.showInfo();
		}else {
			System.out.println("The flight with flight number:" + flight.getFlightNumber() + 
                    " has exceeded its load capacity and cannot carry the order.");
		}
	}
}
class Airline {
	private String customerNumber;
	private CustomerInfo customerInfo;
	private Flight flight;
	private double sumWeight;
	private double sumCost;
	private double discount;
	public Airline(String customerNumber, CustomerInfo customerInfo, Flight flight,double discount) {
		super();
		this.customerNumber = customerNumber;
		this.customerInfo = customerInfo;
		this.flight = flight;
		this.discount = discount;
	}
	public Airline() {
		super();
		// TODO Auto-generated constructor stub
	}
	public String getCustomerNumber() {
		return customerNumber;
	}
	public void setCustomerNumber(String customerNumber) {
		this.customerNumber = customerNumber;
	}
	public CustomerInfo getCustomerInfo() {
		return customerInfo;
	}
	public void setCustomerInfo(CustomerInfo customerInfo) {
		this.customerInfo = customerInfo;
	}
	public Flight getFlight() {
		return flight;
	}
	public void setFlight(Flight flight) {
		this.flight = flight;
	}
	
	public double getDiscount() {
		return discount;
	}
	public void setDiscount(double discount) {
		this.discount = discount;
	}
	public boolean isValid() {
		Iterator<Goods> itr = customerInfo.getList().iterator();
		sumWeight = 0;
		while(itr.hasNext()) {
			Goods goods = itr.next();
			this.sumWeight += goods.getCount().getActualWeight();
			this.sumCost += goods.getCount().getCost();
		}
		return sumWeight < flight.getMaxload();
	}
	public void showInfo() {
		System.out.printf("客户:%s(%s)订单信息如下:\n",customerInfo.getCustomer().getName(),
				customerInfo.getCustomer().getPhoneNumber());
		System.out.println("-----------------------------------------");
		System.out.println("航班号:" + flight.getFlightNumber());
		System.out.println("订单号:" + customerInfo.getPostMessage().getOrderNumber());
		System.out.println("订单日期:" + customerInfo.getPostMessage().getOrderDate());
		System.out.println("发件人姓名:" + customerInfo.getPostMessage().getSender().getName());
		System.out.println("发件人电话:" + customerInfo.getPostMessage().getSender().getPhoneNumber());
		System.out.println("发件人地址:" + customerInfo.getPostMessage().getSender().getAddress());
		System.out.println("收件人姓名:" + customerInfo.getPostMessage().getRecivier().getName());
		System.out.println("收件人电话:" + customerInfo.getPostMessage().getRecivier().getPhoneNumber());
		System.out.println("收件人地址:" + customerInfo.getPostMessage().getRecivier().getAddress());
		System.out.println("订单总重量(kg):" + this.sumWeight);
		System.out.println(customerInfo.getPay().Show() + String.format("%.1f", this.sumCost * discount));
		System.out.println("");
		System.out.println("货物明细如下:");
		System.out.println("-----------------------------------------");
		System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
		Iterator<Goods> itr = customerInfo.getList().iterator();
		for(int i = 1; itr.hasNext(); i++) {
			Goods goods = itr.next();
			System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",i,goods.getName(),
					goods.getCount().getActualWeight(),goods.getCount().getRate(),
					goods.getCount().getCost());
		}
	}
}
class Flight {
	private String flightNumber;
	private String startAirport;
	private String endAirport;
	private String flightDate;
	private int maxload;
	public Flight(String flightNumber, String startAirport, String endAirport, String flightDate, int maxload) {
		super();
		this.flightNumber = flightNumber;
		this.startAirport = startAirport;
		this.endAirport = endAirport;
		this.flightDate = flightDate;
		this.maxload = maxload;
	}
	public Flight() {
		super();
		// TODO Auto-generated constructor stub
	}
	public String getFlightNumber() {
		return flightNumber;
	}
	public void setFlightNumber(String flightNumber) {
		this.flightNumber = flightNumber;
	}
	public String getStartAirport() {
		return startAirport;
	}
	public void setStartAirport(String startAirport) {
		this.startAirport = startAirport;
	}
	public String getEndAirport() {
		return endAirport;
	}
	public void setEndAirport(String endAirport) {
		this.endAirport = endAirport;
	}
	public String getFlightDate() {
		return flightDate;
	}
	public void setFlightDate(String flightDate) {
		this.flightDate = flightDate;
	}
	public int getMaxload() {
		return maxload;
	}
	public void setMaxload(int maxload) {
		this.maxload = maxload;
	}
}
class CustomerInfo {
	private Customer customer;
	private ArrayList<Goods> list;
	private PostMessage postMessage;
	private Pay pay;
	public CustomerInfo(Customer customer, ArrayList<Goods> list, PostMessage postMessage, Pay pay) {
		super();
		this.customer = customer;
		this.list = list;
		this.postMessage = postMessage;
		this.pay = pay;
	}
	public CustomerInfo() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	public ArrayList<Goods> getList() {
		return list;
	}
	public void setList(ArrayList<Goods> list) {
		this.list = list;
	}
	public PostMessage getPostMessage() {
		return postMessage;
	}
	public void setPostMessage(PostMessage postMessage) {
		this.postMessage = postMessage;
	}
	public Pay getPay() {
		return pay;
	}
	public void setPay(Pay pay) {
		this.pay = pay;
	}
}
abstract class Goods {
	protected String goodsNumber;
	protected String name;
	protected double length;
	protected double width;
	protected double height;
	protected double grossWeight;
	protected double volumeWeight;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getLength() {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
	public double getWidth() {
		return width;
	}
	public void setWidth(double width) {
		this.width = width;
	}
	public double getHeight() {
		return height;
	}
	public void setHeight(double height) {
		this.height = height;
	}
	public double getGrossWeight() {
		return grossWeight;
	}
	public void setGrossWeight(double grossWeight) {
		this.grossWeight = grossWeight;
	}
	
	public String getGoodsNumber() {
		return goodsNumber;
	}
	public void setGoodsNumber(String goodsNumber) {
		this.goodsNumber = goodsNumber;
	}
	protected Count count;
	
	public Count getCount() {
		return count;
	}
	public void setCount(Count count) {
		this.count = count;
	}
	public Goods(String goodsNumber,String name, double length, double width, double height, double grossWeight) {
		super();
		this.goodsNumber = goodsNumber;
		this.name = name;
		this.length = length;
		this.width = width;
		this.height = height;
		this.grossWeight = grossWeight;
		volumeWeight = getVolumeWeight();
		//count = new Count(this.grossWeight, this.volumeWeight);
	}
	public double getVolumeWeight() {
		return  ((this.length * this.width * this.height) / 6000);
	}
}
class GoodsOfNormal extends Goods{
	public GoodsOfNormal(String goodsNumber, String name, double length, double width, double height,
			double grossWeight) {
		super(goodsNumber, name, length, width, height, grossWeight);
		// TODO Auto-generated constructor stub
		this.count = new countOfNormal(this.grossWeight, this.volumeWeight);
	}
}
class GoodsOfExpedite extends Goods{
	public GoodsOfExpedite(String goodsNumber, String name, double length, double width, double height,
			double grossWeight) {
		super(goodsNumber, name, length, width, height, grossWeight);
		// TODO Auto-generated constructor stub
		this.count = new countOfExpedite(this.grossWeight, this.volumeWeight);
	}
}
class GoodsOfDangerous extends Goods{
	public GoodsOfDangerous(String goodsNumber, String name, double length, double width, double height,
			double grossWeight) {
		super(goodsNumber, name, length, width, height, grossWeight);
		// TODO Auto-generated constructor stub
		this.count = new countOfDangerous(this.grossWeight, this.volumeWeight);
	}
}
abstract class Count {
	protected double grossWeight;
	protected double volumeWeight;
	public Count() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Count(double grossWeight, double volumeWeight) {
		super();
		this.grossWeight = grossWeight;
		this.volumeWeight = volumeWeight;
	}
	public double getActualWeight() {
		if (grossWeight < volumeWeight) {
			return this.volumeWeight;
		} else {
			return this.grossWeight;
		}
	}
	public abstract double getRate();
//	public double getRate() {
//		double actualWeight = getActualWeight();
//		double rate = 0;
//		if (actualWeight < 20 && actualWeight >= 0) {
//			rate = 35.0;
//		} else if (actualWeight < 50) {
//			rate = 30.0;
//		} else if (actualWeight < 100) {
//			rate = 25.0;
//		} else if (actualWeight >= 100) {
//			rate = 15.0;
//		}
//		return rate;
//	}
	
	public double getCost() {
		return getActualWeight() * getRate();
	}
}
class countOfNormal extends Count {
	public countOfNormal() {
		super();
		// TODO Auto-generated constructor stub
	}
	public countOfNormal(double grossWeight, double volumeWeight) {
		super(grossWeight, volumeWeight);
		// TODO Auto-generated constructor stub
	}
	@Override
	public double getRate() {
		double actualWeight = getActualWeight();
		double rate = 0;
		if (actualWeight < 20 && actualWeight >= 0) {
			rate = 35.0;
		} else if (actualWeight < 50) {
			rate = 30.0;
		} else if (actualWeight < 100) {
			rate = 25.0;
		} else if (actualWeight >= 100) {
			rate = 15.0;
		}
		return rate;
	}
}
//加急货物
class countOfExpedite extends Count {
	public countOfExpedite() {
		super();
		// TODO Auto-generated constructor stub
	}
	public countOfExpedite(double grossWeight, double volumeWeight) {
		super(grossWeight, volumeWeight);
		// TODO Auto-generated constructor stub
	}
	@Override
	public double getRate() {
		double actualWeight = getActualWeight();
		double rate = 0;
		if (actualWeight < 20 && actualWeight >= 0) {
			rate = 60.0;
		} else if (actualWeight < 50) {
			rate = 50.0;
		} else if (actualWeight < 100) {
			rate = 40.0;
		} else if (actualWeight >= 100) {
			rate = 30.0;
		}
		return rate;
	}
}
//危险货物
class countOfDangerous extends Count {
	
	public countOfDangerous() {
		super();
		// TODO Auto-generated constructor stub
	}
	public countOfDangerous(double grossWeight, double volumeWeight) {
		super(grossWeight, volumeWeight);
		// TODO Auto-generated constructor stub
	}
	@Override
	public double getRate() {
		double actualWeight = getActualWeight();
		double rate = 0;
		if (actualWeight < 20 && actualWeight >= 0) {
			rate = 80.0;
		} else if (actualWeight < 50) {
			rate = 50.0;
		} else if (actualWeight < 100) {
			rate = 30.0;
		} else if (actualWeight >= 100) {
			rate = 20.0;
		}
		return rate;
	}
}
class Person {
	protected String name;
	protected String phoneNumber;
	protected String address;
	public Person(String name, String phoneNumber, String address) {
		super();
		this.name = name;
		this.phoneNumber = phoneNumber;
		this.address = address;
	}
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhoneNumber() {
		return phoneNumber;
	}
	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
}
class Customer extends Person {
	public Customer(String name, String phoneNumber, String address) {
		super(name, phoneNumber, address);
	}
	public Customer() {
		super();
		// TODO Auto-generated constructor stub
	}
}
class CustomerOfIndividual extends Customer {
	public CustomerOfIndividual() {
		super();
		// TODO Auto-generated constructor stub
	}
	public CustomerOfIndividual(String name, String phoneNumber, String address) {
		super(name, phoneNumber, address);
		// TODO Auto-generated constructor stub
	}
}
class CustomerOfCorporate extends Customer {
	public CustomerOfCorporate() {
		super();
		// TODO Auto-generated constructor stub
	}
	public CustomerOfCorporate(String name, String phoneNumber, String address) {
		super(name, phoneNumber, address);
		// TODO Auto-generated constructor stub
	}
}
class Sender extends Person {
	public Sender(String name, String phoneNumber, String address) {
		super(name, phoneNumber, address);
	}
	public Sender() {
		super();
		// TODO Auto-generated constructor stub
	}
}
class Recevier extends Person {
	public Recevier(String name, String phoneNumber, String address) {
		super(name, phoneNumber, address);
	}
	public Recevier() {
		super();
		// TODO Auto-generated constructor stub
	}
}
class PostMessage {
	private Sender sender;
	private Recevier recivier;
	private String flightNumber;
	private String orderDate;
	private String orderNumber;
	public PostMessage(Sender sender, Recevier recevier, String flightNumber, String orderDate, String orderNumber) {
		super();
		this.sender = sender;
		this.recivier = recevier;
		this.flightNumber = flightNumber;
		this.orderDate = orderDate;
		this.orderNumber = orderNumber;
	}
	public PostMessage() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Sender getSender() {
		return sender;
	}
	public void setSender(Sender sender) {
		this.sender = sender;
	}
	public Recevier getRecivier() {
		return recivier;
	}
	public void setRecevier(Recevier recivier) {
		this.recivier = recivier;
	}
	public String getFlightNumber() {
		return flightNumber;
	}
	public void setFlightNumber(String flightNumber) {
		this.flightNumber = flightNumber;
	}
	public String getOrderDate() {
		return orderDate;
	}
	public void setOrderDate(String orderDate) {
		this.orderDate = orderDate;
	}
	public String getOrderNumber() {
		return orderNumber;
	}
	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}
}
abstract class Pay {
	public abstract String Show();
}
class WechatPay extends Pay {
	@Override
	public String Show() {
		return "微信支付金额:";
	}
}
class ALiPay extends Pay {
	@Override
	public String Show() {
		return "支付宝支付金额:";
	}
}
class Cash extends Pay {
	@Override
	public String Show() {
		return "现金支付金额:";
	}
}(2)类间关系分析及类图
- Main 类:用于获取用户输入信息。依赖于Scanner、Iterator、ArrayList类;与Airline类、Customer类、Goods类、Pay类等存在创建实例的依赖关系。
- Person 类及其子类:Customer(客户类)、Sender(发件人)、Recevier(收件人)继承自父类Person ,复用Person的姓名、电话、地址属性。
- Customer 类及其子类:CustomerOfIndividual(个人客户类)、CustomerOfCorporate(企业客户类)继承自Customer类。
- Goods 类及其子类:GoodsOfNormal(普通货物类)、GoodsOfExpedite(加急货物类)、GoodsOfDangerous(危险货物类)继承自Goods类 ,并分别关联countOfNormal、countOfExpedite、countOfDangerous类用于计费。
- Count 类及其子类:countOfNormal(普通货物计费类)、countOfExpedite(加急货物计费类)、countOfDangerous(危险货物计费类)继承自Count类,实现不同计费规则。
- Pay 类及其子类:WechatPay(微信支付类)、ALiPay(支付宝支付类)、Cash(现金支付类)继承自Pay类 ,实现Show()方法展示支付信息。
- Airline 类:关联CustomerInfo类、Flight类 ,持有客户编号和折扣信息;依赖Iterator<Goods>计算货物重量和费用。
- CustomerInfo 类:聚合Customer类、ArrayList<Goods>、PostMessage类、Pay类 ,整合客户相关信息。
- PostMessage 类:聚合Sender类、Recevier类 ,关联航班号、订单日期和编号,记录邮寄信息。
- Flight 类:独立类,记录航班号、起飞机场、降落机场、航班日期、最大载重等信息。

(3)SourceMoniter分析代码:

具体信息:
查看代码
 Metrics Details For File 'Main.java'
--------------------------------------------------------------------------------------------
Parameter				Value
=========				=====
Project Directory			C:\Users\25734\eclipse-workspace\SouseMoniter\src\test2\
Project Name				分析结果5
Checkpoint Name				Baseline
File Name				Main.java
Lines					748
Statements				132
Percent Branch Statements		10.6
Method Call Statements			67
Percent Lines with Comments		3.5
Classes and Interfaces			4
Methods per Class			3.75
Average Statements per Method		6.73
Line Number of Most Complex Method	8
Name of Most Complex Method		Main.main()
Maximum Complexity			14
Line Number of Deepest Block		46
Maximum Block Depth			4
Average Block Depth			1.96
Average Complexity			2.00
--------------------------------------------------------------------------------------------
Most Complex Methods in 3 Class(es):	Complexity, Statements, Max Depth, Calls
Airline.Airline()			1, 1, 2, 1
Airline.Airline()			1, 5, 2, 1
Airline.getCustomerInfo()		1, 1, 2, 0
Airline.getCustomerNumber()		1, 1, 2, 0
Airline.getDiscount()			1, 1, 2, 0
Airline.getFlight()			1, 1, 2, 0
Airline.isValid()			2, 7, 3, 6
Airline.setCustomerInfo()		1, 1, 2, 0
Airline.setCustomerNumber()		1, 1, 2, 0
Airline.setDiscount()			1, 1, 2, 0
Airline.setFlight()			1, 1, 2, 0
Airline.showInfo()			1, 11, 2, 13
ALiPay.Show()				1, 1, 2, 0
Main.main()				14, 68, 4, 46
--------------------------------------------------------------------------------------------
Block Depth				Statements
0					8
1					23
2					70
3					28
4					3
5					0
6					0
7					0
8					0
9+					0
--------------------------------------------------------------------------------------------一、基本信息
- 代码规模
- Lines:748 行。
- Statements:132 条语句。
 
二、代码结构指标
- 控制流相关
- Percent Branch Statements:10.6%,即分支语句占比,说明代码中条件判断(如if - else、switch )等逻辑占整体语句比例适中,代码执行路径有一定复杂性。
- Method Call Statements:67 条,反映方法调用的频繁程度,表明代码通过方法调用来组织功能逻辑,模块化程度尚可。
 
- 注释情况
- Percent Lines with Comments:3.5%,注释行占比很低,意味着代码中注释较少,会降低代码可读性和可维护性,后续理解和修改代码难度较大。
 
- 类与方法统计
- Classes and Interfaces:4 个,代表文件中定义的类和接口数量。
- Methods per Class:平均每个类 3.75 个方法,表明类的功能丰富度一般,可能存在功能划分不够精细的情况。
- Average Statements per Method:平均每个方法 6.73 条语句,说明方法的平均规模不算小,方法逻辑可能相对复杂。
 
三、复杂度指标
- 最复杂方法
- Line Number of Most Complex Method:8 行,Name of Most Complex Method为Main.main(),Maximum Complexity是 14。说明该方法在代码中的位置以及它的复杂程度较高,可能存在较多条件判断、循环或嵌套逻辑。
 
- 代码块深度
- Line Number of Deepest Block:46 行,Maximum Block Depth:4,Average Block Depth:1.96,反映代码中代码块存在一定深度的嵌套,整体结构有一定复杂度。
 
- 平均复杂度
- Average Complexity:2.00,表示代码整体的平均复杂程度处于中等水平,但存在个别复杂方法拉高整体复杂度。
 
四、改进方向
- 
- 增加代码注释,提升代码可读性。
- 对复杂方法(如Main.main() )进行重构,拆分功能,降低复杂度。
- 合理划分功能模块,增加类和接口数量,提升代码的可维护性和扩展性。
 
体会:这是航空货运管理系统的第二次迭代,在第一次迭代的基础之上,需求增加主要体现在货物的多样性,计算方式、支付方式的多样性上。这种设计更加贴近生活,同时透过对问题的分析,也让我更好的理解面向对象编程设计原则在程序设计上的重要性。总体上来说,这次迭代的工作量因为有了第一次迭代的合理设计,在代码修改添加方面工作量不算大。但要求对多态以及功能划分有更加清晰的认识。
三、踩坑心得
- 第一次迭代中的信息获取:由于平时处理批量数据的主方法很大一部分是有老师给的主方法作为提示,导致我在设计用户信息输入时总是会出现一些细节上的问题(例如next()、nextLine()的区别,nextInt()后要使用nextLine()处理缓存区的换行符),平时通过老师给的主方法作为参考,这些问题尚未暴露,在这次依靠自己完成整道题的时候,就会出现小问题上的卡壳。透过这个问题,我更加明白了基础知识的重要性。
- 类的分类:第一次看到题目的时候,我选择先进行类的划分,一开始是没有设计Count类,而是将它划归于Goods类当中,但在后续代码复现的时候,我发现代码冗余,逻辑不合理,不符合生活当中的职责划分(计算货物的计费重量以及运费应当由航空公司来完成),后面选择开辟一个计算类完成对货物的计算。事实证明,在第二次迭代的时候,由于货物种类的不同,所对应的计算方式也有所差异。也感谢自己在第一次迭代能够将计算功能模块划分出来。
- 迭代器的使用:第一次接触迭代器是在电梯迭代作业当中老师给出的主方法中的信息输出,但是由于对迭代器的认识学习不够,还是出了一些问题。示例for(int i = 1; itr.hasNext(); i++) { Goods goods = itr.next(); System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n",i,goods.getName(), goods.getCount().getActualWeight(),goods.getCount().getRate(), goods.getCount().getCost()); }
示例当中的Goods goods = itr.next();我给忽略掉了,导致输出过程老是只输出一行的信息。后面查询资料才得知,迭代器需要一个容器来接受其引用。
四、改进建议
- 对代码还可以进一步划分使得整体满足单一功能原则,例如对CustomerInfo进行细化。
- 将Person类进行抽象,将具体的代码实现交由其子类。
五、总结
收获及建议:
收获:
经过这一次的迭代训练,提升最大的方面是对继承和多态上的理解,其次是设计原则的理解,然后再是类的划分。这一次的迭代训练需要做的继承类是比较多的,这对我们的提升帮助很大。同时由于需要对整体两方面(航空公司和客户)进行构思,这使得我对问题的拆分能力得到提升。
建议:
希望以后的迭代训练能维持在这个难度水平,之前电梯的迭代在算法设计上耗费太多时间,但是对编程方面的提升相较这次,个人觉得更低。最后还是感谢老师花费时间设计这次迭代作业,这次的迭代作业做的还是比较顺利,也给我带来了一定的信心。
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号