您的位置:首页 > 其它

电梯系统OO设计

2015-09-17 17:43 281 查看
理论上应该先黑盒用例,分析需要求,系统边界的输入输出,再白盒类图。 但是对于现实世界模拟的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。

class Box {
int direction; // 0 up, 1 down, 2 stopped
int currentPos; //current position
int capacity; // max load
final static int MAX_FLOOR = 100;
volatile boolean destinations[] = new boolean[MAX_FLOOR];
volatile boolean pickups[][] = new boolean[MAX_FLOOR][2]; //0 for up, 1 for down
int highestTo = -1; // the farest upper floor to go
int lowestTo = -1; // the farest lower floor to go
volatile boolean on = true; //on or off
Building building;
int numRequest = 0;
Object signal = new Object();

public void call(int floor, int direction) {
synchronized(signal) {
if (!pickups[floor][direction]) {
pickups[floor][direction] = true;
++numRequest;
if (highestTo < 0 || floor > highestTo) highestTo = floor;
if (lowestTo < 0 || floor < lowestTo) lowestTo = floor;
signal.notify();
}
}
}
public void setDestination(int floor) {
synchronized(signal) {
if (!destinations[floor]) {
destinations[floor] = true;
++numRequest;
signal.notify();
}
}
}
public void shutdown() {
on = false;
synchronized(signal) {
signal.notify();
}
}

private void open() {building.open(currentPos); /*first open the building door, then the box's*/ }
private void close() {building.close(currentPos);}
private void stop() {}
private void positionChanged() {
if (pickups[currentPos][direction] || destinations[currentPos]) {
stop();
open();
//Thread.sleep(5000);
close();
synchronized(signal) {
if (pickups[currentPos][direction]) {pickups[currentPos][direction] = false; --numRequest;}
if (destinations[currentPos]) {destinations[currentPos] = false; --numRequest;}
if (highestTo == currentPos) highestTo = -1;
if (lowestTo == currentPos) lowestTo = - 1;
}
//resume();
}
}
private void run() {
while (on) {
synchronized (signal) {
if (numRequest == 0) {
direction = 2; //stopped
signal.wait(); //wait signal here if no jobs to do
}
//decide up or down, handle upper request first.
if (highestTo > 0 ) direction = highestTo > currentPos ? 0 : 1;
else if (lowestTo > 0) direction = lowestTo < currentPos ? 1 : 0;
}

if (direction == 0) { //up
for (int i = currentPos + 1; i <= highestTo; ++i) {
++currentPos;
positionChanged();
}
}
else if (direction == 1) {//down
for (int i = currentPos - 1; i >= lowestTo; --i) {
--currentPos;
positionChanged();
}
}

}
}
}
//楼building:用户请求电梯的媒介,和轿厢box有个一对一关联关系,向轿厢box发call消息,轿厢到达某层,向buildng发某层open的消息。
class Building {
Box box;
public void call(int floor, int direction ) { box.call( floor, direction);}
public void open(int floor) {}
public void close(int floor) {}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: