电梯系统OO设计

来源:互联网 发布:mac os x iso镜像 大小 编辑:程序博客网 时间:2024/05/19 22:01

理论上应该先黑盒用例,分析需要求,系统边界的输入输出,再白盒类图。 但是对于现实世界模拟的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 stoppedint currentPos; //current positionint capacity;  // max loadfinal 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 downint highestTo = -1; // the farest upper floor to goint lowestTo = -1; // the farest lower floor to govolatile boolean on = true; //on or offBuilding 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; //stoppedsignal.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) { //upfor (int i = currentPos + 1; i <= highestTo; ++i) {++currentPos;positionChanged();}}else if (direction == 1) {//downfor (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) {}}



0 0
原创粉丝点击