面向对象1

一、前言

航空器配载与货运管理系统1

(1)题量情况:代码中一共有六个类(Flight、cargo、loadManifest、sort、isoverload、Main)总的代码行数130多行,代码量不大。一共要实现通过装载顺序输出货物的信息,输出装载的总重量以及该航班的最大载重量,输出配载状态,判断是否达到了超载的情况。
(2)难度:难度不大,关键就是分析好几个类之间的关系即可,总体的难度偏小
(3)知识点:
封装特性:成员变量全部是私有化,不可以外部直接修改属性。
单一职责原则:每一个类只做一件事: Flight、cargo:纯实体类,只存储数据,不写业务逻辑;loadManifest:负责货物添加、重量求和; sort:单独封装排序算法,与业务代码解耦; isoverload:只负责超载判定;Main:只做输入调用与结果输出。
使用动态数组:使用Arraylist保存货物对象,实现对象的批量存储与遍历
image

排序方式:选择排序的思路是每一轮遍历找出当前未排序区间重量最大的货物,放置到靠前位置,和航空器配载优先装载重货的业务逻辑贴合。相比于冒泡排序需要在遍历过程中频繁交换元素,选择排序每一轮仅执行一次交换,交换次数更少,逻辑清晰,不容易在对象交换环节出错。

航空器配载与货运管理系统2

(1)题量情况:代码中一共有九个类(position、Cargo、CargoCompartment、Flight、isoverload、LoadDispatcher、InputValidator、Overall_status、Main)总的代码行数220多行,代码量不大。

在1的基础上增加了航班货运配载模块,增加了个实现货物装载的输出,输出当前货舱装载情况。
(2)难度:相较于1的难度有所提升,主要是实现的业务双重超载判断;单货舱载重上限+航班全局超载,并且又多使用了一个动态数组用来存储货舱的信息。
(3)知识点:

关联关系:货舱与装载的货物是聚合关系:货舱销毁了,但是货物本身还是存在的(聚合关系:是公有的,整体和部分时可以独立存在的);货舱与其位置时组合关系:货舱没有了,其Position也不在存在(组合关系:是私有的,整体和部分是捆绑在一起的)
集合框架:增加了货舱的动态数组

image

分支逻辑:多层超载判断,返回状态码,用switch统一输出状态,使用状态及机思想
image

航空器配载与货运管理系统3

(1)题量情况:代码中一共有十一个类(position、Cargo、CargoCompartment、luggage、passenger、Flight、WeightBalanceCalculator、isoverload、LoadDispatcher、InputValidator、Main)总的代码行数360多行。在2的基础是实现飞机载重平衡配载(中心配平)的业务,一道综合性的面向对象的大题。
(2)难度:属于中等偏上,

UML类关系变多,Flight 聚合货舱、旅客;CargoCompartment 组合 position、聚合 Cargo,需要理清多层整体 - 部分关系.
双重约束:① 货舱局部载重上限;② 飞机重心区间安全约束(不再只看重量,还要看重心位置),两个条件都要满足。
边界条件增多。
(3)知识点:
关联关系:组合关系:passenger内部 new luggage、CargoCompartment构造内部 new position,生命周期绑定;
聚合关系:Flight持有List、List,货舱、旅客对象可以独立存在,再加入航班;
集合框架:与2的基础上增加了乘客信息
image

排序方式:改成使用冒泡排序,不再是选择排序的方式
增强鲁棒性要求:在数据录入过程中,要对数据进行合法性验证,如果发现有非法输入,立即停止应用程序运行。

image

二、设计与分析

航空器配载与货运管理系统1

本程序为航班基础货物配载程序,实现航班信息录入、货物信息录入、货物按重量降序排序、舱单打印、超载判定功能,先确定可以分成几个类别来写,以及每个类别对应的属性和方法有哪些 。

总体的业务(除了Main)可以分成5个类别,分别是:

Fight(航班类){属性1:航班号,属性2:最大承载重量};方法{获取航班号(getFightNo),获取最大承载重量(getmaxWeight)}
cargo(货物类){属性1:货物名称,属性2:货物重量};方法{获取货物名称(getCargoname),获取货物重量(getCargoWeight)};
loadManifest(装载舱单清单){属性1:货物的列表(是一个动态数组,方便后续输出)};方法{增加货物(addcargo),总重量的计算(totalWeight),排序(getCargoList)(注意这里的排序方法只能是选择排序,效率更好)};
sort(排序类,因为loadManifest里面的方法太多,可以把排序分出来){属性:货物的列表};方法{通过选择排序的方法将对象互换,可以使用到ArrayList的set(位置,要换的对象)};
isoverload(是否超载){属性:总的重量}{方法:与最大承载重量比较并输出};
1794475880145
image

Project Directory
项目路径
Project Name
项目名称
Checkpoint Name
快照名称
File Name
文件名
Lines
总行数
Statements
有效语句数
Percent Branch Statements
分支语句占比
Method Call Statements
方法调用次数
Percent Lines with Comments
注释行占比
Classes and Interfaces
类与接口总数
Methods per Class
每个类平均方法数
Average Statements per Method
单个方法平均语句数
Line Number of Most Complex Method
最复杂方法所在行号
Name of Most Complex Method
最复杂方法名称
Maximum Complexity
最大圈复杂度
Line Number of Deepest Block
最深嵌套代码块行号
Maximum Block Depth
最大嵌套深度

从SoucrceMonitor分析得到,有效的语句有44条,平均每个类1.20个方法,每个方法平均1.83条语句,平均圈复杂度1.20,整体复杂度很低。全文件复杂度最高的方法是loadManifest.totalWeight(),最大圈复杂度仅为 2,最深代码块深度为 4,不存在超长嵌套、臃肿函数,代码拆分比较清爽。

在UML类关系上,loadManifest和cargo是聚合关系,装载舱单内部持有货物列表,舱单和货物对象生命周期相互独立;sort类、isoverload类和loadManifest、Main 之间属于依赖关系,仅在需要排序、超载校验的时候临时调用;

image

图2-1类图

解释和心得:

(1)面向对象编程 中,不同功能拆分成不同类,实体类保存数据,工具类完成排序,代码结构清晰,增加注释,方便后期维护

(2)ArrayList和c语言里面的数组访问方式不一样,数组用[下标],集合 读取.get(下标)、修改.set(下标,对象),下标只是数字,不能直接当做对象传入 set 方法,这个点很容易编译报错。

(3)

sortList.set(i,sortList.get(maxindex));//将i位置的对象变成maxindex的

sortList.set(maxindex,temp);

这是动态数组的交换对象,因为cargo里面存在两个属性,但是一半c语言里面交换的方式是不太匹配的,使用的方法是sortList(自己定义的变量).set(想要换到哪个位置,想要换的内容);

(4)方法调用时,形参实参要匹配,有参数的方法调用时必须传入对应类型的数据,否则直接编译失败。写代码时注意检查方法签名,不要写多余的变量名。

(5)整体而言,这个相对较简单,只需要想清楚分为几个类别,每个类别需要干什么事情即可.

航空器配载与货运管理系统2

本程序是带多货舱的航班货物配载调度程序,实现航班、货舱、位置、货物的管理,支持按货物重量降序优先装载、单货舱载重校验、航班整体业载与起飞重量双重超载判断、输入范围校验,

(1)先确定好几个类别,根据题目而言,我们必须要有的类是Position(位置类)、Cargo(货物类)、CargoCompartment(货舱类)、Flight(航班类)、LoadDispatcher(调度类)、InputValidator(校验类)。根据题目的输出格式,我么可以看到最后需要我们进行超载的区分,所以我们可以再建立一个(区分超载类)isoverload,再区分超载后,有不同情况的输出,这时我们也可以建立一个(整体超载输出情况)Overall_status。所以我们总共有8个类别

(2)分析这8个类别的静态属性和动态方法

Position(位置类){属性:row 行号,column 列号};方法 {getPosName (),获取位置名称,返回位置字符串标识};
Cargo(货物类){属性:cargoname 货物名称,cargoWeight 货物重量,targetID 目标货舱编号};
方法 {getCargoname (),获取货物名称;

getCargoWeight (),获取货物重量;

getTargetID (),获取目标货舱 ID,指明该货物需要装入哪个货舱};

CargoCompartment (货舱类){属性:id 货舱编号,maxWeight 货舱最大载重,positions 位置集合,cargos 货舱内装载的货物列表(这个是为了方便后续获得货物的详细信息)};
方法 {addCargo (Cargo cargo),尝试向货舱添加货物,判断加入后是否超载,成功返回 true,失败返回 false;

getCurrentWeight (),遍历货物列表,计算货舱当前已装载总重量;

getId (),获取货舱编号;

getCargos (),获取当前货舱内所有货物的列表;

getMaxWeight (),获取货舱允许的最大载重};

Flight(航班类){属性:flightNO 航班号,maxpayloadWeight 航班最大业载重量,maxtakeoffweight 航班最大起飞重量,cargoCompartments 航班包含的货舱列表(为了方便后续去获取货舱的详细信息和cargos作用一样)};
方法 {

getFlightNO (),获取航班编号;

getMaxWeight (),获取航班最大业载重量;

add (CargoCompartment c),向航班添加货舱对象;

findcargoCompartment (String id),根据货舱编号查找对应的货舱对象,找不到返回 null;gettotalWeight (),遍历所有货舱,计算航班全部货舱当前装载总重量;

getMaxpayloadWeight (),获取航班最大业载;

getMaxtakeoffweight (),获取航班最大起飞重量;

Cragolist (),获取航班下全部货舱的列表};

LoadDispatcher(调度类){属性:无};
方法 {

sortCargos (List CargoList),采用选择排序,对货物列表按重量降序排序;FindCargo (List CargoList,String cargoname),根据货物名称在货物列表中查找对应的货物对象,找到返回货物,找不到返回 null}。

InputValidator(校验类){属性:无};
方法 {

incheckINT (int val,int min,int max),校验整数是否在指定区间内,用于输入合法性检查;incheckFLOAT (Double val,Double min,Double max),校验浮点数是否在指定区间内,用于输入合法性检查};

isoverload(超载判断类){属性:totalWeight 总装载重量,flight 关联的航班对象};
方法 {isoverload (Flight flight),构造方法,绑定需要判断超载的航班;

condition (),读取航班总重量,和航班最大业载、最大起飞重量对比,返回代表超载情况的状态码};

Overall_status(整体配载状态类){属性:无};
方法 {status (int choice),接收超载状态码,输出对应的配载提示文本,提示航班是否超载以及超载类型};

image
image
Project Directory
项目路径
Project Name
项目名称
Checkpoint Name
快照名称
File Name
文件名
Lines
总行数
Statements
有效语句数
Percent Branch Statements
分支语句占比
Method Call Statements
方法调用次数
Percent Lines with Comments
注释行占比
Classes and Interfaces
类与接口总数
Methods per Class
每个类平均方法数
Average Statements per Method
单个方法平均语句数
Line Number of Most Complex Method
最复杂方法所在行号
Name of Most Complex Method
最复杂方法名称
Maximum Complexity
最大圈复杂度
Line Number of Deepest Block
最深嵌套代码块行号
Maximum Block Depth
最大嵌套深度

通过 SourceMonitor 对本货运航班管理代码进行度量分析,项目有效语句共 44 条,平均每个类包含 1.20 个方法,每个方法平均 1.83 条语句,平均圈复杂度 1.20,整体复杂度水平很低。结合度量明细可见,大部分为构造方法与 getter 方法,无复杂分支逻辑;项目内圈复杂度最高的方法为 isoverload.condition (),圈复杂度为 5,其次 CargoCompartment.addCargo ()、Flight.findcargoCompartment () 等方法圈复杂度为 2,最深代码块嵌套深度为 5,仅少量代码存在多层分支判断,不存在超长嵌套、臃肿函数,代码拆分清爽,整体可读性与可维护性较好。

在 UML 类关系上,CargoCompartment 和 position 是组合关系,货舱内部包含货位,货舱销毁时对应的货位也随之销毁;CargoCompartment 和 Cargo 是聚合关系,一个货舱可以包含多件货物,货舱销毁,货物对象可以被分配到其他货舱;Flight 和 CargoCompartment 是聚合关系,航班包含多个货舱;其余为依赖关系,与1的基本差不多,增加了货舱类

image
image

图2-2类图

解释和心得:

(1)position 是组合,在java组合和聚集可以用私有和公有来区分,组合就相当于是私有的,这个东西不可以替换,而聚集就公有的是可以被替换的,这个position是组合就是私有,所以只能在CargoCompartment里面被定义

(2)cargos是聚合也是聚集,是公有的,可以被替换,所以是在外部进行声明传参的。

(3) 主要的 核心还是分清楚类别,根据职责分类,将不同的功能拆解到独立类中

(4)本航班货运配载程序核心关键点:

①类的划分:梳理业务实体,抽象出位置、货物、货舱、航班等实体类,以及调度、校验、状态判断等工具类;

②对象关系建模:区分组合、聚集两种关联,在 UML 类图中正确绘制,体现面向对象实体之间的包含关系;

③装载逻辑:先对货物按重量降序排序,再遍历货物,匹配目标货舱 ID,调用货舱addCargo()判断货舱载重是否超限;

④两层超载判断:第一层是单个货舱内部载重校验;第二层是航班整体载重校验,分别对比最大业载、最大起飞重量,输出不同等级告警; ⑤输入校验:借助工具类InputValidator对输入数量、数值范围做合法性校验,过滤非法输入。

航空器配载与货运管理系统3

本程序是带多货舱的航班货物配载调度程序(基于2基础上增加的),实现航班、货舱、位置、货物、旅客、行李、载重平衡、超载校验、输入校验的管理,支持货舱载重校验、航班重心配平计算、输入范围校验,输出航班载重平衡舱单并评估重心是否安全。

(1)先确定好几个类别,根据题目而言,我们要增加3个类别,passenger(旅客类)、luggage(行李类)、WeightBalanceCalculator(载重平衡计算类),但是同时在Flight类、inputValidator类、isoverload类都要进行修改

(2)分析这3个类别的静态属性和动态方法

passenger(旅客类)
属性:{name・旅客编号,Luggageweight・行李对象;静态属性 standardweight・单人标准旅客重量;}

方法:{getname (),获取旅客编号;

getLuggageweight (),获取旅客总重量(旅客自重 + 行李重量);}

luggage(行李类)
属性:{luggageweight・行李重量;}

方法:{getLuggageweight (),获取行李重量;}

WeightBalanceCalculator(载重平衡计算类)
属性:{emptyweight・空机重量,emptyarm・空机重心力臂,passengerarm・旅客舱平均力臂,arm1・前货舱力臂,arm2・后货舱力臂,MAC_leading_edge・平均气动弦前缘位置,MAC_length・平均气动弦长度;}

方法:{generateLoadSheet (Flight flight),计算旅客总重、旅客力矩、货物总重、货物力矩、全机总重、全机总力矩、实际重心、重心百分比,返回计算结果数组; safe (Double CG),判断重心百分比是否在安全区间,安全返回 true,危险返回 false;}

Flight(航班类):增加了passengers・航班旅客列表;passengerList (),获取航班下全部旅客的列表;
isoverload(超载判断类):修改了输出的格式以及判断的条件

image

LoadDispatcher(调度类):修改了排序的方式改成了冒泡排序。

image

image
image

Project Directory
项目路径
Project Name
项目名称
Checkpoint Name
快照名称
File Name
文件名
Lines
总行数
Statements
有效语句数
Percent Branch Statements
分支语句占比
Method Call Statements
方法调用次数
Percent Lines with Comments
注释行占比
Classes and Interfaces
类与接口总数
Methods per Class
每个类平均方法数
Average Statements per Method
单个方法平均语句数
Line Number of Most Complex Method
最复杂方法所在行号
Name of Most Complex Method
最复杂方法名称
Maximum Complexity
最大圈复杂度
Line Number of Deepest Block
最深嵌套代码块行号
Maximum Block Depth
最大嵌套深度

通过 SourceMonitor 对本航班载重平衡配载调度代码进行度量分析,项目有效语句共 44 条,平均每个类包含 1.20 个方法,每个方法平均 1.83 条语句,平均圈复杂度 1.20,整体复杂度水平很低。结合度量明细可见,大部分为构造方法与 getter 方法,无复杂分支逻辑;全项目复杂度最高的方法为WeightBalanceCalculator.generateLoadSheet(),圈复杂度为 5,其次isoverload.condition()、WeightBalanceCalculator.safe() 圈复杂度为4、CargoCompartm

ent.addCargo()、CargoCompartment.getCurrentWeight()、Flight.findcargoCompartment()、Flight.gettotalWeight()等方法圈复杂度为 2,代码最大块深度为 6,仅少量代码存在多层分支判断,不存在超长嵌套、臃肿函数,代码拆分清爽,整体可读性与可维护性较好。

在 UML 类关系上,在2的基础上增加了Luggage和Paseenger之间的组合关系。

image
image

解释和心得:

(1)Luggage是组合,它与Passenger是组合关系,原因:如果乘客被摧毁了,那么他携带的行李就不可能存在。

(2)WeightBalanceCalculator与Flight是依赖关系,依赖是在某种场景下,需要借助另外一个类来帮助,WeightBalanceCalculator需要借助Flight得到乘客的重量,以及各个货舱的重量

(4)本航班配载计算程序核心关键点:

①类的划分:梳理业务实体,抽象出位置、货物、货舱、航班等实体类,以及调度、校验、状态判断等工具类;

②对象关系建模:区分组合、聚集、依赖关联关系,在 UML 类图中正确绘制,体现面向对象实体之间的包含关系;

③装载逻辑:每装载货物进去就要判断是否达到该仓的最大载重

④重心的计算:物理公式的转化

⑤输入校验:借助工具类InputValidator对输入数量、数值范围做合法性校验,过滤非法输入,以及要判断是否是负数。

三、采坑心得:
对于1而言,我们要注意,排序必须使用选择排序的方式才可以通过测试,以及里面的关联关系、逻辑关系没有搞清楚,开始采用单个变量存储,无法批量添加多个货物,扩展性很差,对于后面新加的货物没有很好的分配;对于2而言,重要是position的组合关系,以及超载的情况下输出条件要把(超载)给删除了,开始不知道可以在货舱里面建立货物数组,这样的话,就可以直接加入该舱的货物;对于3而言,最终要的就是物理公式,以及前后舱满了的输出情况,整数型的校验,最小值应该是1,而不是0.

posted @ 2026-11-12 17:57  hyhelen  阅读(3)  评论(0)    收藏  举报