软件工程第四个程序:结对项目 —— 电梯调度问题


框架设计

我们设计在一栋大楼的电梯系统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

 

posted on 2016-04-03 22:21  Mr.Winter  阅读(761)  评论(1编辑  收藏  举报