电梯系列——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协作图 前言 本单元作业在优化方面确实有一些想法值得分享,故单开一篇博客分享一下三次作业的优化以及架构. 三次作业的共同之处 ...
随机推荐
- 尝鲜Java 12新特性:switch表达式
Java 12将在两个月后(2019/3/19)发布,现已进入RDP1阶段,确定加入8个JEP.其中对Java语法的改进是JEP 325: switch表达式.于是我迫不及待,提前感受一下更先进的语言 ...
- 从0开始的Python学习016异常
简介 当你的程序不能正常运行的时候,Python会在控制台打印一段提醒,告诉你一个错误,这个错误就是异常. 错误 我在控制台写了一段无效的代码,将print()的括号去掉,在执行这条语句的时候,系统提 ...
- Aspnet mvc移除WebFormViewEngine
为了提高mvc的速度,在Global.asax中移除WebFormViewEngine protected void Application_Start() { RemoveWebFormEngine ...
- PHP将汉字转为拼音
没什么难度,最大的难点应该是需要有一个汉字-拼音库. <?php function spell($str, $ishead=0){ $restr = ''; $str = trim($str); ...
- python基础 常见用法
1.python计时器timeit模块 1)timeit 模块定义了接收两个参数的Timer类,两个参数都是字符串. 参数1:要计时的语句或者函数 参数2:为参数1构建环境的导入语句 2)Timer对 ...
- 自定义class类的简单使用
晚上闲着无事, 然后看了阮老师的es6 的类用法,包括继承. 然后, 想着在vue中怎么使用class . 1. 定义一个 classmodel.js 文件. 里面包含如下代码: 2.接着, 在vue ...
- JS中让新手倍感震惊、违反直觉、出乎意料、的一些知识点汇总记录
本文记录在自己学习js过程中,违反直觉,出乎意料,倍感震惊的知识点.当然,不了解这个知识点,很容易出错,因为毕竟违反直觉,出乎意料,倍感震惊嘛! 1. 两个内容一样的数组竟然不相等? var a = ...
- jQuery 与 Ajax 的应用
Ajax 全称为 "Asynchronous JavaScript and XML"(异步 JavaScript 和 XML ),它并不是指一种单一的技术,而是有机地利用了一系列交 ...
- Flutter控制屏幕旋转
特定页面旋转屏幕很简单: SystemChrome.setPreferredOrientations([ ... ]); 数组中是您要支持的屏幕方向. 如果想在特定页面固定横屏, 您可以这样写: @o ...
- WebSocket原理
一 . WebSocket原理 1.1.背景 WebSocket 是基于Http 协议的改进,Http 为无状态协议,基于短连接,需要频繁的发起请求,第二 Http 只能客户端发起请求,服务端无法主动 ...