软件工程第四个程序:结对项目 —— 电梯调度问题
框架设计
我们设计在一栋大楼的电梯系统MyElevatorSystem里,各处的电梯组是独立的。即一个电梯组有一个外部调度管理ElevatorManager,处理电梯外部按钮的响应,把消息传递给所管理的工作中的
电梯RunningElevator;而在电梯内部,所有按钮的响应直接由工作中的电梯RunningElevator自己完成。类的框架关系如图。
具体设计
1.主入口MyElevatorSystem
程序需要一个主入口,MyElevatorSystem类就是程序的主入口,现实中电梯的程序早就写在芯片里了,这里我们先初始化一个电梯系统,包括两个外部调度管理ElevatorManager,和四个工作的
电梯RunningElevator。同时,把电梯添加进所属的外部调度管理ElevatorManager中,并开启电梯线程。后期在此创建和显示窗口。
2.外部调度管理ElevatorManager
使用Vector<RunningElevator> vector记录所辖的电梯,当电梯外部按钮被按下时,把楼层等信息传递给所辖的工作中的电梯RunningElevator去处理。ElevatorManager类也是个线程类。
3.工作中的电梯RunningElevator
整个程序的核心,记录一部电梯的全部信息,包括编号,限制,当前载重,最大载重,当前停靠楼层,目标停靠楼层,外部请求记录 和 内部请求记录。
>>>这里我们也是突发奇想:电梯所处的楼层,不应只是一个数值,而应该还带有方向。当电梯在10层时,有可能电梯在向上运行,也可能在向下运行,这是两个不同的状态。所以我们把向
上运行的10层定义为10层,把向下运行的10层定义为30层;具体的对应关系如图所示。
这样一来对内外请求的记录也可以简化。
private String InsideRequireFloors = "00000000000000000000" + "00000000000000000000";// 四十个0 private String OutsideRequireFloors = "00000000000000000000" + "00000000000000000000";// 四十个0
用setOutsideRequire(int floor)与setInsideRequire(int floor)函数来改变OutsideRequireFloors与InsideRequireFloors的值。
改用40个字符来标记请求对于电梯的调度也带来很大方便。
RunningElevator类的searchNextFloor()函数用来寻找下一个应答楼层。寻找可以从当前的楼层开始向后找,而不用考虑上下方向问题。具体的寻找方式如下代码。
public void searchNextFloor() { // 寻找下一个应答楼层 int fo = OutsideRequireFloors.substring(currentFloor - 1).indexOf('1'); int fi = InsideRequireFloors.substring(currentFloor - 1).indexOf('1'); if (fi > 0) { if (fo > 0 && fo < fi) { // 内部请求,而外部请求更近时,先响应外部请求。 move(fo + currentFloor - 1); } else { // 没有更近的外部请求,响应内部请求。 move(fi + currentFloor - 1); } } else if (fo > 0) { // 内部没请求,而外部有请求,响应内部请求。 move(fo + currentFloor - 1); } else { // 如果没有向下的需求,就重新定义向上。 currentFloor = 40 - currentFloor; } }
方法应该没错,但这个寻找算法还是存在问题的。。。(几个来回后就死循环)
测试
由于突发奇想的表示方法,寻找算法进展缓慢,界面只做了个极简版。。。
上述的算法都实现的差不多了我们就测试了一下,按下按钮执行以下代码:
JButton btnNewButton = new JButton("测 试"); btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { //在10层有乘客按下第一组电梯的外部按钮。 ElevatorFrame.setString(new String("在10层有乘客按下第一组电梯的外部按钮")); MyElevatorSystem.OutsideRequire(1, 10, 1); try { Thread.sleep(18000); System.out.println("延迟18秒"); } catch (InterruptedException e) { e.printStackTrace(); } //电梯门关闭后,在一号电梯内,按下15层. ElevatorFrame.setString(new String("电梯门关闭后,在一号电梯内,按下15层")); MyElevatorSystem.re1.setInsideRequire(15); } });
首先在10层有乘客按下第一组电梯的外部按钮,当电梯到达10层后电梯开门,乘客进入电梯,当电梯门关闭后,乘客在一号电梯内,按下15层。一号电梯上升至15层,开门。
结果如图。
程序的华丽版界面再等等吧。。。
结对成员:曹鑫宇&王远远
队友博客:http://www.cnblogs.com/yuan7180/
Coding:https://coding.net/u/Mr_winter/p/ESE04/git
J.X.Dinosaur