电梯系列——OO Unit2分析和总结
一、摘要
本文是BUAA OO课程Unit2在课程讲授、三次作业完成、自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客。主要包含设计策略、代码度量、BUG测试和心得体会等内容。
二、设计策略分析
2.1 第一次作业
第一次作业较为简单,主要由Elevator线程和InputHandler线程互相合作完成,是消费者、生产者模式,InputHandler生产AllRequest类中的Request对象存在ArrayList中,电梯从中取出Request对象并完成送乘服务。该ArrayList即是共享资源,需要实现互斥。Elevator在内部有人的情况下先完成内部任务,当内部人员为空时去接Request中的乘客,若Request也为空,且输入未完成,则sleep。InputHandler每次增加Request对象都会唤醒电梯。若输入完成,则电梯下班。
2.2 第二次作业
本次作业与上次作业的区别并不大,可捎带的实现在电梯每次到达某一楼层时进行一次是否捎带的判断。如果符合捎带条件,开门后的处理流程和第一次基本是一致的,需要注意的线程安全问题基本没有改变。
2.3 第三次作业
本次作业中有多部电梯,并且电梯有各自运行的楼层,于是某些情况下乘客需要转乘来到达目标楼层。本人在设计中是通过对乘客类的修改实现,记录乘客的目标楼层,并先把目标楼层替换为中转楼层,在乘客出门后将增加一个请求。在电梯是否捎带的策略设计中,每部电梯只捎带从自己运行楼层出发,目的地也为自己运行楼层的请求,或者从自己运行的非换乘楼层出发的请求。设计中需要保证所有可能的请求都能顺利完成,不会出现无法到达的情况或者没有电梯响应请求的情况。也增加了新的线程安全问题,需要重新考虑电梯下班的条件,以及增加请求时也需要唤醒sleep的电梯线程。
2.4 对调度策略和实用性的思考
本次作业中,有很多指导书中的要求只是对实际情况的一种抽象,存在某些细节与实际不符合,也有考虑不周的情况。
例如对负重,现实中一定不会按人数,而会按照具体的重量来决定,那么在乘客输入请求时,电梯是无法预判是否会超载的。因此,基于超载预判的调度策略优化在现实中并不合理。
其次,作业中从未思考乘客的自主选择,除了反悔等,乘客可能提前下电梯、采用自己的换乘方案等。
最后,某些整体时间缩短的策略可能导致个别乘客等待时间的过长,可能会引起使用者的不满。
2.5 对优化的思考
本部分仅仅考虑在指导书规定中的优化,将有与上一节讨论(即与实际应用)矛盾或不合理的地方,仅可能带来性能上的提升。
首先,电梯在不载人的时候可以运行到某个特定楼层,例如中间楼层,或者换乘楼层,或者基于乘坐数据集的最可能接客地点。
其次,预判电梯将超载时,如果请求可以由其他电梯完成,同时调度其他电梯到该楼层。
还有基于当前所有请求的最优调度模拟。如果请求可以由不同电梯完成,或者楼层的访问顺序可以改变,可以预先计算所有调度方案所用时间,再选择最快的方法。但此方法对性能有较大影响。
三、程序规模统计
3.1 第一次作业
类图

代码度量


主线程UML时序图

Elevator UML时序图

3.2 第二次作业
类图

代码度量


主线程时序图

Elevator UML时序图

3.3 第三次作业
类图

代码度量



主线程时序图

Elevator UML时序图

3.4 分析
优点:设计中可扩展性强,后两次作业没有对之前的作业进行大规模的重构,类图具有一定相似性,设计中基本符合SOLID原则中的里氏替换原则、接口隔离原则、依赖倒置原则。
缺点:单一责任原则不是非常符合,Elevator的run、canTake、RunningCheck等方法复杂度过高,对Elevator类还可以进行拆分,可以将优化、调度策略等单独用一个类实现;第三次作业中不同的电梯设计不符合开放封闭原则,三部特殊电梯可以使用继承的方式实现。
四、测试中的bug分析
4.1 自我程序bug分析
本单元三次作业中,本人自己的bug仅仅只有第三次作业有1个bug,具体如下。
} else if (name == 'C' && !el.isInC(toFloor)) {
this.toNewFloor = toFloor;
if (el.isInA(toFloor)) {
this.toFloor = 1;
} else {
if (floor <= toFloor) {
this.toFloor -= 1;
} else {
this.toFloor += 1;
}
}
this.special = true;
}
含BUG的代码
} else if (name == 'C' && !el.isInC(toFloor)) {
this.toNewFloor = toFloor;
if (el.isInA(toFloor)) {
this.toFloor = 1;
} else {
if ((floor <= toFloor && floor != 3) || (toFloor == 2)) {
this.toFloor -= 1;
} else {
this.toFloor += 1;
}
}
this.special = true;
}
修复后代码
此为设计上的考虑不周。BUG位于People类的构造器中,即在分析特殊乘客的转乘路线时,设计出现了错误,导致乘客不能正确地转乘,从而无法到达目标楼层。
在本单元我的程序中,并没有出现有关线程安全问题的bug。
4.2 互测其他人bug分析
本单元中互测时遇到的bug也比较少,例如请求完成电梯线程sleep后唤醒时出现的重复到达楼层的问题,和第三次作业中特殊楼层请求不能被正确完成的bug。基本都为设计上的小问题,没有遇到线程安全的问题。
五、Hack策略分析
5.1 Hack策略
Hack分别基于代码和统一共性问题进行测试。统一的问题如
线程安全问题的测试主要通过阅读代码来进行判断,这次互测时也没有发现线程安全方面的问题,因此没有特意设计基于某个线程安全bug的针对性数据输入。
5.2 与第一单元的差异
第一单元中,学生主要出现bug的地方都是关于输入输出格式方面的问题,Hack主要基于指导书要求中容易被忽视或者设计上易出现错误的数据,而程序功能性问题比较少。本单元中使用统一接口后,bug只剩下功能性问题和线程安全问题。
六、心得体会
6.1 线程安全
本单元中开始了多线程的设计,在以前简单地学习JAVA中我对多线程有一点点了解,但之前从未考虑过安全问题。通过理论课程的学习和三次作业的练习,大概了解了保证线程安全的重要性和方法。本单元的练习中,主要是输入结束和电梯暂时无任务、电梯下班等需要仔细考虑,输入完成后不意味着电梯就已经完成任务,电梯内仍然可能有人,而第三次作业中,输入完成、电梯内无人后仍然可能有人还没到达目标楼层,这些都是要考虑的地方。而且有关线程安全的测试也更加困难,不一定会引起错误而且具有不可再现性,需要在设计中考虑周全并进行多次测试。
6.2 设计原则
本单元的设计方面现实性比较强,易从实际角度分析电梯的调度要求,可能出现的各种情况等,功能的设计方面思考起来比较容易。在设计原则方面,由于功能的复杂总体较低,有些原则没有顾全,例如单一责任原则,本身电梯需要完成的调度还算比较简单,所以没有分离设计,对更复杂功能的程序实现是存在问题的。而基本上没有使用继承、抽象等,无法体现里氏替换原则。本单元只是对多线程设计的简单初探,之后的更多要求更加复杂的设计中需要更加考虑到SOLID原则才能使程序具有更好的健壮性和扩展性,符合工业化的要求。
电梯系列——OO Unit2分析和总结的更多相关文章
- UML系列——OO Unit4分析和学期总结
一.本单元的架构设计 1.类图 第一次 第二次 2.关键方法和架构简述 总体而言是读取图的时候就完成大部分计算(完成缓存),调用查询方法时只是展示计算的结果,少部分直接计算.主要是设计了各种自己定义的 ...
- 多项式求导系列——OO Unit1分析和总结
一.摘要 本文是BUAA OO课程Unit1在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.本文第二部分介绍三次作业的设计思路,主要以类图的形 ...
- JML规格编程系列——OO Unit3分析和总结
本文是BUAA OO课程Unit3在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.主要包含JML相关梳理.SMT Solver验证.JML单元 ...
- OO Unit2多线程电梯总结博客
OO Unit2多线程电梯总结博客 传说中的电梯居然就这样写完了-撒花
- OO Unit2 总结
OO Unit2 总结 OO课Unit2电梯仿真项目技术回顾 BUAA.1823.邓新宇 2020/4/17 Part1 设计策略 从多线程的协同和同步控制方面,分析和总结自己三次作业的设计策略 第一 ...
- SonarQube系列二、分析dotnet core/C#代码
[前言] 本系列主要讲述sonarqube的安装部署以及如何集成jenkins自动化分析.netcore项目.目录如下: SonarQube系列一.Linux安装与部署 SonarQube系列二.分析 ...
- 【HANA系列】SAP HANA跟我学HANA系列之创建分析视图一
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA跟我学HANA系 ...
- OO电梯系列总结与反思
目录 前言 HW5 度量分析 UML类图与协作图 bug分析 HW6 度量分析 UML类图与协作图 bug分析 HW7 度量分析 UML类图与协作图 bug分析 SOLID原则 感想 前言 紧张刺激的 ...
- OO电梯系列优化分享
目录 前言 HW5 HW6 第二次作业uml协作图 HW7 第三次作业uml协作图 前言 本单元作业在优化方面确实有一些想法值得分享,故单开一篇博客分享一下三次作业的优化以及架构. 三次作业的共同之处 ...
随机推荐
- selenium-日志文件的使用(十二)
概述 在自动化测试中,如果测试失败需要对错误的错误的代码或者测试case进行分析,进行分析时最好的方法是在项目中添加日志文件,通过日志文件的分析定位出现错误的原因. 这样可以保持自动化测试用例的健壮性 ...
- lodash源码分析之去重--uniq方法
lodash.js包是node开发中常用的js工具包,里面有许多实用的方法,今天分析常用的一个去重方法---uniq 用法 _.uniq([2, 1, 2]) // => [2, 1] 源码包 ...
- Python入门测试
1.比如自然数10以下能被3或者5整除的有,3,5,6和9,那么这些数字的和为23. 求能被3或者5整除的1000以内数字的和 multiple_of_threes=[] for multiple_o ...
- 如何取消Microsoft账户登录电脑
手贱用Microsoft账户登录了一下笔记本里面的日历,TNND微软直接就把你电脑的登录账户直接改成了微软账户,花了1个小时才搞回去. 步骤如下: 0--脑残微软的设计,点了下日历,弹出下面这个,绝对 ...
- 【心得】Lattice Diamond 后端约束实战小结
[博客导航] [导航]FPGA相关 IOB约束 参考<插入IO寄存器和位置约束---lattice&diamond>,推荐的方法是: 1.在strategy设置[Map Desig ...
- SQL 行转列的运用
适用场景:需要将行数据转换成列数据 例子: 现在有一个学生的成绩表 但是我们需要将每个学生的成绩汇集到一条数据上,这时候就可以用到行转列. 代码如下 一.不使用 PIVOT SELECT ),[St ...
- remote: Permission to user_name/Code.git denied to other_user_name. fatal: unable to access 'https://github.com/user_name/Code.git/': The requested URL returned error: 403
Error msg: $ git push remote: Permission to xxx/Code.git denied to xxxxxx. fatal: unable to access ' ...
- ThinkPad T400 键帽下面的X支架的安装方法
有一台古老的T400,清理键盘的时候,X支架老化断了,淘宝买了几个支架,研究一下安装方法: 1.注意支架方向:上面是横向的细支架,下面是两个小孔2.用小螺丝刀把下面的两个小孔推进键盘下面的两个金属钩里 ...
- Photoshop给河边婚片加上唯美的霞光
<点小图查看大图> 最终效果 1.打开原图素材大图,按Ctrl + Alt + 2 调出高光选区,按Ctrl + Shift + I 反选得到暗部选区,然后创建曲线调整图层,对RGB.红. ...
- (六)jdk8学习心得之Stream流
六.Stream流 1. 什么是stream流 现阶段,可以把stream流看成一个高级版的Iterator.普通的Iterator只能实现遍历,遍历做什么,就需要具体些功能代码函数了.而这个stre ...