电梯系统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) {}
}
识别类,最主要的原则是封装,数据和数据的操作封装成一个类:
轿厢 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) {}
}
相关文章推荐
- Yoshua Bengio等大神传授:26条深度学习经验
- 压缩解压操作
- 计算机器内存数量+引入和显示ARDS成员
- Vector的使用
- VM参数简介
- 我的第一篇博文
- 为.NET搭建Linux的开发环境,鄙视那些将简单事情复杂化的人
- Android平台的开发环境的发展演变
- windows7系统下如何安装windows xp系统(无法识别硬盘,删除隐藏分区)
- 动态的django项目
- IOS URL加载系统 UIWebView URL拦截
- 自己实现的JDBC工具类
- hdu5441
- 笔记04 WPF对象引用
- 前端小知识
- [算法]回文检测
- 创建你的第一个App——新建一个项目
- c#调用带输出参数的存储过程
- SQL 学习资源汇总
- 《Ruby 元编程》笔记