面向对象总结性Blog_01:单部电梯调度
一、前言
通过完成这三次题目集,我有了一些感悟。
首先,这三次题目集的主要知识点有:---基础语法、校验算法、类设计(SRP原则)、正则表达式、状态管理、电梯调度(完整OOP+设计模式)
其中最重要的当属电梯调度(完整OOP+设计模式)
然后,这三次题目集一共有5+3+3也就是11道题,题量不算大,但五脏俱全,能够有效地培养面向对象的思维。
其次,这三次题目集的总体难度中等,但电梯调度这一系列的题目对于面向对象程序初学者的我来说挑战性十足
二、设计与分析
1、 第五次题目集-单部电梯调度源码分析
第五次题目集的电梯题目要求编写一个Java程序,设计一个电梯类,包含状态管理、请求队列管理以及调度算法。
当时,在提交这道题目并通过后,我长出了一口气。但到了现在写Blog总结的时候,我发现当时写的代码"非常的面向过程",不像是在用Java语言,而像是在用C语言完成这道题目。
以下使用Source Monitor分析我的代码
代码分析总览图:

由于刚刚接触面向对象不久,第一次设计电梯OOP并没有理解面向对象的要点,我的代码中面向过程的部分偏多,把几乎所有的方法一股脑塞进Elevator类中。
Elevator类具体分析图:

从这张图可以直观地看出:我的代码中 函数深度(Block Depth)偏大,而 函数复杂度(Function Complexity)的平均复杂度(Avg Complexity)偏小,代码注释(Comments)很少,每个类平均包含方法个数过多,这也能看出我的代码还是以面向过程为主,而非面向对象。
这应该是每个面向对象初学者共有的经历:编写OOP程序时还是习惯性地面向过程。接下来要考虑的就是如何一点点地把这一大段面向过程的代码转变为面向对象的代码,也就是第六次题目集的任务。
2、第六次题目集-单部电梯调度源码分析
第六次题目集的电梯题目要求对之前电梯调度程序进行迭代性设计,目的为解决电梯类职责过多的问题,类设计要求遵循单一职责原则(SRP)
估计老师料到了我们从面向过程的思维转变到面向对象的思维需要一个过渡期,电梯题目的迭代也是循循渐进,让我们往面向对象的思维上靠拢。
这次要求不能只使用电梯类,必须包含但不限于设计电梯类、乘客请求类、队列类以及控制类,单一职责原则(SRP)具有面向对象的特色,我根据要求在上一次代码的基础上进行修改,也是顺利通过了这次的题目,但我知道我的代码还有很多处理的不够好的地方,比如:使用了大量的if-else语句......
以下使用Source Monitor分析我的代码
代码分析总览图:

可以看到这次我创建了很多个类,由面向过程向面向对象转变,努力遵循SRP原则。
其中最重要的当属Controller类,先来看看这个类
Controller类具体分析图:

可以看到,在Controller类中,平均包含方法个数达到了合格的水平,相较于上一次有所进步,但函数深度(Block Depth)还是偏大,而函数复杂度(Function Complexity)也提升了不少,代码注释(Comments)很少,每个函数平均包含的语句个数(Average Statements per Method)太多了,并不达标,我的代码还有很多很多需要改进的地方
值得一提的是,在第五次题目中,我使用字符串(String)来表示电梯的方向和状态,而这次我使用了枚举(enum)来表示,更规范也更简单好用。
第七次题目集中要求设计一个乘客类(Passenger),我这次的代码中就有,但这次也就是第六次中我写的乘客类并不符合第七次中的要求,与乘客请求类没有太大的差别,第七次题目集教会了我如何编写一个有效的乘客类
3、第七次题目集-单部电梯调度源码分析
第七次题目集要求对之前电梯调度程序再次进行迭代性设计,加入乘客类(Passenger),取消乘客请求类,类设计要求遵循单一职责原则(SRP)
这次的题目让我们进一步掌握了SPR原则与分层架构,让我对OOP有了更深的认识
以下使用Source Monitor分析我的代码
代码分析总览图:

可以看到我简化了代码并大致实现了题目要求,现在再来看看控制类(Controller)
Controller类具体分析图:

emmmmm......尴尬的是好像还是和上次代码的问题差不多,代码的结构方面还需改良
那再来看看乘客类(Passenger)
Passenger类具体分析图:

各项指标都偏低,其实乘客类就17行语句(Statements),Source Monitor的参考价值不大
三、踩坑心得
在编写一系列电梯迭代程序的代码时,我遇到了许许多多奇奇怪怪的错误。
- 比如Scanner类的使用:Scanner类看似是一个很常用很简单的类,但我在使用时发现了一个比较容易忽略的点,就是当你在一个方法中创建了一个Scanner对象,比如
Scanner sc = new Scanner(System.in),在方法末尾对其进行关闭sc.close,然后在另一个方法中再创建一个Scanner对象,比如Scanner input = new Scanner(System.in)(注意,两个对象都用System.in),IDE就会报错:NoSuchElementException,关于这个问题我百思不得其解,遂上网搜索,找到了这样一篇Blog:https://www.cnblogs.com/zccjy/p/16041182.html,这篇Blog大致说明了报错原因并给出了初步的解决方法,使我受益良多
我的解决方法与他不同,我第一次使用Scanner类是在main方法中,第二次使用是在控制类的一个方法中,我使用传参的方式把sc对象传入另一个方法中,如图:
![]()


也是成功解决了这个问题
-
还有关于pta上代码长度限制的问题
![]()
可以看到,代码长度限制是16KB,我以前都会忽略这个限制,但这次我的代码写的太多太繁杂了,pta提示代码长度超过限制
我就去文件夹中看了看我代码的大小,大概是17KB左右,刚好超出了1KB,随后就开始简化我的代码,比如有些if-else语句可以进行简化,很多语句都是重复的可以写在一起,有的没用到的get或set方法可以删去(反正现在没别人用我的方法删了也没事,偷笑),化简之后大小在长度限制以内,顺利提交
这让我意识到编写代码时不仅要完成正常运行并输出正确结果的目标,还要让自己的代码尽量精简美观不冗杂 -
当我做第六次题目集的电梯题目时,需要在第五次的基础上进行改进,但这时候我以及有点看不懂我的代码了,因为我几乎没写注释,而且我的代码很冗杂。我以前对注释是不太在乎的,相信很多人也和我一样。但实际上注释是十分重要的,没写注释时,我自己看自己写的代码都费力,更不要说拿给别人看了,还是要养成写注释的好习惯。
四、改进建议
在对自己的代码进行回顾后,结合我踩过的坑,有如下改进建议:
- 进一步化简自己的代码,减少if-else语句的大量使用。
- 强化OOP思想,做到每一个部分都模块化
- 踩坑心得中提到我使用传参的方式把sc对象传入另一个方法中,这种做法实际上并不好,不是长久之计,如果大量的方法需要用到Scanner类,那就要对很多的方法都传入sc对象了,这很麻烦,需要另寻出路
- 在代码复用方面,部分重复逻辑(如电梯方向判断)可提取为工具类。
- 如果这个电梯程序还可以进一步迭代的话,比如需要支持多种电梯控制算法时(如SCAN算法、LOOK算法等),需要支持不同类型的电梯(如高速电梯、货运电梯)时,可以引入接口;当请求类型需要扩展(如紧急请求、VIP请求等特殊请求)或需要实现不同调度策略的层级结构时,可以引入继承。
五、总结
-
学到了什么
通过完成本阶段的三次题目集,我从面向过程过渡到了面向对象,进一步理解了面向对象编程(OOP)思想,并初步掌握了SRP原则和分层设计。同时,我的算法与逻辑能力也得到了提升,在电梯题目中我学到了LOOK算法。不仅如此,我的代码结构也逐步得到了优化,从“面条代码”转变到分层设计,锻炼了我的编写代码能力 -
进一步学习
这次的单部电梯调度题目只是用到了Java的基础语法知识,并没有用到继承与多态、接口等内容,还需要进一步学习继承与多态、接口的相关知识,以应对将来更具挑战性的任务 -
对课程的改进意见
这段时间学习Java以来,我最深的感受就是"散"和"多",比如,Java中自带的方法不少,我们在做一个题目时,常常会用到陌生的方法,这些陌生的方法又特别多,用下一个方法就会把上一个忘掉了,方法很分散但又要去使用,不好串联起来,上课时也有同样的感觉,希望老师能出出招



浙公网安备 33010602011771号