电梯系统OO设计

电梯系统OO设计

 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/binling/article/details/48520391

理论上应该先黑盒用例,分析需要求,系统边界的输入输出,再白盒类图。 但是对于现实世界模拟的OO,个人感觉先emulate现实世界,初步识别类和类之间的关系,再用用例和顺序图丰富、修正类图。

识别类,最主要的原则是封装,数据和数据的操作封装成一个类:

轿厢 box:封装轿厢的状态:位置、方向、静止还是运动,capacity,  pickup列表,目的地列表

楼building:用户请求电梯的媒介,和轿厢box有个一对一关联关系,向轿厢box发call消息,轿厢到达某层,向building发某层open的消息。

从控制驱动的角度,有2种控制流(主动对象)

1)轿厢box:不停地运转,根据请求的情况,运行或者停止等待信号

2)人:1是人向building发消息,building再 forward到box;2)是人向轿厢发消息,设置要去的目的地楼层

和VODController类似,内部一个驻留线程,类似一个状态机运行着,同时多个点可以接收异步消息更新数据。

亮点是一个事件机制,每经过一层,触发一个positionChanged的事件

总结:OO系统,就是一个互相发消息的对象系统,对象之间靠消息交互

常见的控制流模型:

1) 顺序执行,exit

2)无专门驻留线程,完全消息驱动,类似一般的web service,request/response模式。

3) 有一个驻留线程在run, (定时运行或者受信号控制),同时也可以接受异步消息更新数据,为社么说是异步消息,因为它只是通过update数据来影响状态机的运行,不需要返回什么结果。基于工作队列的处理系统也属于这种模型,但更简单,FIFO处理就行,电梯模型的复杂在于,系统会根据当前所有request的情况做一个调度,并不是简单的FIFO。

 

  1.  
    class Box {
  2.  
    int direction; // 0 up, 1 down, 2 stopped
  3.  
    int currentPos; //current position
  4.  
    int capacity; // max load
  5.  
    final static int MAX_FLOOR = 100;
  6.  
    volatile boolean destinations[] = new boolean[MAX_FLOOR];
  7.  
    volatile boolean pickups[][] = new boolean[MAX_FLOOR][2]; //0 for up, 1 for down
  8.  
    int highestTo = -1; // the farest upper floor to go
  9.  
    int lowestTo = -1; // the farest lower floor to go
  10.  
    volatile boolean on = true; //on or off
  11.  
    Building building;
  12.  
    int numRequest = 0;
  13.  
    Object signal = new Object();
  14.  
     
  15.  
    public void call(int floor, int direction) {
  16.  
    synchronized(signal) {
  17.  
    if (!pickups[floor][direction]) {
  18.  
    pickups[floor][direction] = true;
  19.  
    ++numRequest;
  20.  
    if (highestTo < 0 || floor > highestTo) highestTo = floor;
  21.  
    if (lowestTo < 0 || floor < lowestTo) lowestTo = floor;
  22.  
    signal.notify();
  23.  
    }
  24.  
    }
  25.  
    }
  26.  
    public void setDestination(int floor) {
  27.  
    synchronized(signal) {
  28.  
    if (!destinations[floor]) {
  29.  
    destinations[floor] = true;
  30.  
    ++numRequest;
  31.  
    signal.notify();
  32.  
    }
  33.  
    }
  34.  
    }
  35.  
    public void shutdown() {
  36.  
    on = false;
  37.  
    synchronized(signal) {
  38.  
    signal.notify();
  39.  
    }
  40.  
    }
  41.  
     
  42.  
    private void open() {building.open(currentPos); /*first open the building door, then the box's*/ }
  43.  
    private void close() {building.close(currentPos);}
  44.  
    private void stop() {}
  45.  
    private void positionChanged() {
  46.  
    if (pickups[currentPos][direction] || destinations[currentPos]) {
  47.  
    stop();
  48.  
    open();
  49.  
    //Thread.sleep(5000);
  50.  
    close();
  51.  
    synchronized(signal) {
  52.  
    if (pickups[currentPos][direction]) {pickups[currentPos][direction] = false; --numRequest;}
  53.  
    if (destinations[currentPos]) {destinations[currentPos] = false; --numRequest;}
  54.  
    if (highestTo == currentPos) highestTo = -1;
  55.  
    if (lowestTo == currentPos) lowestTo = - 1;
  56.  
    }
  57.  
    //resume();
  58.  
    }
  59.  
    }
  60.  
    private void run() {
  61.  
    while (on) {
  62.  
    synchronized (signal) {
  63.  
    if (numRequest == 0) {
  64.  
    direction = 2; //stopped
  65.  
    signal.wait(); //wait signal here if no jobs to do
  66.  
    }
  67.  
    //decide up or down, handle upper request first.
  68.  
    if (highestTo > 0 ) direction = highestTo > currentPos ? 0 : 1;
  69.  
    else if (lowestTo > 0) direction = lowestTo < currentPos ? 1 : 0;
  70.  
    }
  71.  
     
  72.  
    if (direction == 0) { //up
  73.  
    for (int i = currentPos + 1; i <= highestTo; ++i) {
  74.  
    ++currentPos;
  75.  
    positionChanged();
  76.  
    }
  77.  
    }
  78.  
    else if (direction == 1) {//down
  79.  
    for (int i = currentPos - 1; i >= lowestTo; --i) {
  80.  
    --currentPos;
  81.  
    positionChanged();
  82.  
    }
  83.  
    }
  84.  
     
  85.  
    }
  86.  
    }
  87.  
    }
  88.  
    //楼building:用户请求电梯的媒介,和轿厢box有个一对一关联关系,向轿厢box发call消息,轿厢到达某层,向buildng发某层open的消息。
  89.  
    class Building {
  90.  
    Box box;
  91.  
    public void call(int floor, int direction ) { box.call( floor, direction);}
  92.  
    public void open(int floor) {}
  93.  
    public void close(int floor) {}
  94.  
    }
  95.  

posted @ 2019-02-20 18:10  Bigben  阅读(295)  评论(0编辑  收藏  举报