基于有穷状态机思想的电梯系统
介绍
这次设计的电梯系统是一次软件工程的小组作业(这门课没安排实验,佛),我在这次小组作业中负责的是后端设计和算法设计的部分,多亏了想出来了(不然只能CV了,其实我是这个系统的产品经理
项目上传到了GitHub中,欢迎follow。
设计
设计思想
电梯系统要求采用有穷状态转换机的思想,在我看来就是:”电梯A的状态 + 按下任意电梯按钮 = 电梯A的下一状态“,这种方程的体现。在这个表达式中,我们发现电梯的状态改变是由不同电梯按钮的按下状态来影响的,简单的说就是按钮刺激电梯的状态改变。那么,我们就将电梯形象地设计为激活按钮的接收器,每部电梯可以接收任意数量的按钮,并对之做出反应。
进而考虑到电梯接收激活的按钮,但是并不是按照先激活先刺激电梯状态改变的顺序,所以我们设计了两个优先队列,分别是等待队列和执行队列。执行队列中的按钮会刺激电梯状态改变,而等待队列中的按钮会按照电梯的需要加入到执行队列中。具体的优先和调度逻辑在详细设计中阐述。
最后考虑到多部电梯,激活的按钮具体分配到哪一步电梯,这里也存在着一个分配策略。
上面的内容都来自于我的报告,我同学设计的界面可以很好的反应我们的设计思想:
程序设计
如下图所示,一共设计了5个包和一个程序入口类:
其中,最核心的包是schedule包,有调度队列类scheduleQueue,包含了两个优先队列和一些对优先队列的处理和刷新方法,还有一个调度线程类scheduling,考虑到可以设计多个电梯,所以每部电梯只需要绑定一个调度队列并且开启一个调度线程就可以正常工作了。
其他的,button是按钮包,包含了电梯内部按钮和电梯外部按钮,电梯外部按钮正表示向上,负表示向下;comparator是比较器包,优先队列的比较器;elevator是电梯包,包含了一个核心的anElevator电梯类,用于实例化电梯对象和moveElevator类,表示电梯的移动枚举类;frame是界面包,这个由我同学设计。
调试
程序设计的还是比较简单的,不过设计出来的系统与人们的正常思维逻辑还是有区别,所以大部分时间都花在了Debug上,界面上的那几个队列的表格都是为了方便调试而加上的(没有这个不好调试啊,所以兼职产品经理的我和前端室友开战,逃!)。有两个bug还是让我印象深刻的:
修改执行队列Comparator
问题例子:电梯在1层不同,依次点击电梯外部5层向下和4层向下按钮,电梯先到4层停顿然后在5层停止。正确的移动轨迹应该是先在5层停顿然后在4层停止,等待电梯内部按钮被摁下。
解决方法:修改执行队列中的比较器,两个电梯外部按钮并且和但电梯当前所在层反向的时候,需要将原来的优先级反向。如下图所示:
修改刷新执行队列判断时间
问题例子:电梯在1层停止,依次点击7、6、5、8梯内部按钮,电梯先到第7,然后依次是6、5层,最后停止在8层。
解决方法:出现的这个问题的原因是因为当时设计的时候,仅仅支持在执行队列执行完后,即执行队列为空,才刷新执行队列,现在修改为电梯每移动一次就刷新一次,提高刷新的密度,保证尽量完成能顺便完成的按钮动作。
最后的话
非常欢迎大家修改和完善这个小系统吼,当然也非常期待我大家给我找出的Bug(那得看我又没时间改Bug了)。