用Java写了一个类似电梯模拟器的一段代码,运行了下,还没有发现大问题,记录如下:
基本思路:
模拟电梯运行(为单一电梯,未考虑达到承载上限,最短等待时间等问题)
基本条件:
1、电梯有三种状态:静止,向上,向下。
2、每层的指示灯有三种状态:向上、向下、到达(只开门)。
3、开门上人1秒,每上或下一层用0.1秒。
实现方案:
使用一个队列(可看做时间优先)将所有按钮事件依次入队。
当电梯静止时首先响应队头的按钮事件,并根据按钮楼层和当前楼层的位置确定移动方向; 当向上移动时,将移动到所有亮灯的按钮所在楼层的最高层,当按钮方向和电梯方向一致时或该楼层内部到达按钮亮起时开门;向下移动类似。 当队列中没有按钮事件时,电梯静止。有些类似LOOK算数,但没有按钮事件时不会来回扫描。
使用主线程来控制电梯上下,需要注意同步“设置和获取电梯按钮最高层或按钮最底层数的方法”。
主方法用来不断循环监测:
while(true){ if(!ele.getPushedFloor().isEmpty()){ int nextFloor = ele.getPushedFloor().peek(); if(nextFloor > 0){//向上的按钮 if(ele.getCurFloor() - nextFloor <= 0){ ele.liftUp(); }else if(ele.getCurFloor() - nextFloor > 0){ ele.liftDown(); } }else{//向下的按钮 if(ele.getCurFloor() + nextFloor < 0){ ele.liftUp(); }else if(ele.getCurFloor() + nextFloor >= 0){ ele.liftDown(); } } }else{ ele.setStat(RunningStat.INIT); } Thread.sleep(100); }
电梯上升方法:
public void liftUp() throws InterruptedException{ setStat(RunningStat.UP); int floorIdx = curFloor; while(floorIdx <= this.getLiftTop()){ curFloor = floorIdx; if(btnMap.get(floorIdx).isUpLightOn()){ openDoor(floorIdx, true); btnMap.get(floorIdx).setUpLightOn(false); }else if(btnMap.get(floorIdx).isInnerLightOn()){ justOpenDoor(floorIdx); } /** * 模拟电梯上升 */ Thread.sleep(100); floorIdx++; } synchronized (this) { //需要注意,若“当前层”达到最高层需重新初始化最高层指示变量 if(this.getLiftTop() == curFloor){ this.setLiftTop(bottom - 1); } } }
定义了一个User线程,模拟用户按下按钮
class User implements Runnable{ @Override public void run() { int i = 0; while(i < 10){ i++; int floor = RandomUtils.nextInt(top) + 1; Button btn = ele.getButton(floor); try { if(floor == ele.top){ btn.push(floor, BtnDirec.DOWN); }else if(floor % 2 == 0 || floor == ele.bottom){ btn.push(floor, BtnDirec.UP); }else{ btn.push(floor, BtnDirec.DOWN); } Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } }
还定义了一个EleStat线程,监测电梯状态并打印的后台,日志类似:
The elevator started The elevator is no moving, cur:1 5 floor down light on 5 ↓, The elevator is lift up, cur:1 5 ↓, The elevator is lift up, cur:2 5 ↓, The elevator is lift up, cur:3 5 ↓, The elevator is lift up, cur:4 5 ↓, The elevator is lift up, cur:5 10 floor up light on 5 ↓,10 ↑, The elevator is lift up, cur:6 5 ↓,10 ↑, The elevator is lift up, cur:7 5 ↓,10 ↑, The elevator is lift up, cur:8 5 ↓,10 ↑, The elevator is lift up, cur:9 opening door on floor: 10 lift to:20 5 ↓,20 -, The elevator is lift up, cur:10 12 floor up light on 5 ↓,20 -,12 ↑, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑, The elevator is lift up, cur:10 13 floor down light on 5 ↓,20 -,12 ↑,13 ↓, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑,13 ↓, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑,13 ↓, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑,13 ↓, The elevator is lift up, cur:10 5 ↓,20 -,12 ↑,13 ↓, The elevator is lift up, cur:10 14 floor up light on 5 ↓,20 -,12 ↑,13 ↓,14 ↑, The elevator is lift up, cur:11 opening door on floor: 12 lift to:20 5 ↓,20 -,13 ↓,14 ↑, 。。。
具体代码见附件。
++++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++++++++++++++
经 qiuyibo7777 提示,主方法中那种面向过程的写法对专注面向对象的程序员来说有些不堪入目了。
所以就改写了一个基于“模式”的版本,我选择的是策略模式,不用状态模式,我认为所谓状态模式就是根据事物的上下文状态而采取某种行动,是状态决定了行为;而策略模式为算法决定行为,就比如采用不用的电梯算法(比如平均等待时间最短还是等待时间方差最小)电梯会有不同的行为(上行或下行),相同的状态,不同的算法,可能电梯的行为会不一样。
下面是我改写的主要内容:
UML 类图:
简要说明:
定义了一个总接口ElevatorAction
public interface ElevatorAction { public void action(); }
接口LiftDownAction和LiftUpAction分别继承了ElevatorAction ,TimePriorityLiftDown和TimePriorityLiftUp为具体的实现类。
主方法启动电梯这样写:
Elevator ele = new Elevator(); ele.setTop(top); ele.init(); ele.start();
然后主要就是Elevator的star()方法:
public void start(){ while(true){ ea = getNextAction(pushedFloor, curFloor); ea.action(); } }
每次主循环获取下一个行动的方法,根据当前楼层和下一楼层的数值确定:
public ElevatorAction getNextAction(Queue<Integer> floors, int curFloor){ Integer flag = floors.peek() == null? null : Math.abs(floors.peek()) - curFloor; return getBean(flag); }
然后电梯具体的行为执行类通过ObjectFactory获取:
public ElevatorAction getBean(Integer flag){ String beanName = ObjectFactory.getBeanName(flag); return ObjectFactory.getBean(beanName); }
通过上述方式就避免了繁琐的面向过程的if-else判断,也更容易理解。
TimePriorityLiftDown和TimePriorityLiftUp就是具体的策略类,如果有其他算法可以通过IOC进行灵活配置更改。
注:所谓模式不一定能解决一切问题,但任何问题都应尝试用模式的思维去解决。我认为这是不错的,但我还认为解决问题还是先要有思路,先打好草稿,再有必要的话进行基于模式的重构;若凡事都将模式挂在嘴边,不免有炫耀之嫌,或者就像一个人为人做事老是在那“端着”,又累又没意思。
相关推荐
电梯模拟运行系统是一种用于教学、研究或实验目的的软件或硬件模型,它旨在模拟实际电梯的运行机制。在这个项目中,我们关注的是基于STM8S105K4微控制器的实现,这是一个由STMicroelectronics生产的8位微控制器,...
6. **用户界面**:虽然这是一个控制台版本,但仍然需要一个简单的用户界面来模拟乘客的交互,如输入楼层请求。这可能涉及到控制台I/O操作,如读取用户输入和打印输出。 7. **错误处理**:良好的错误处理机制是必不...
模拟电梯调度:利用JAVA语言编写一个模拟电梯调度程序,要求电梯除最底层、最高层以外每一层外面都有一个上下按钮(第1层只有向上按钮,第6层只有向下按钮),电梯层数为6层,电梯内部有1——6数字按钮和开门按钮,...
这个系统旨在模拟实际生活中电梯的行为,包括接收乘客请求、调度电梯运行、控制电梯的上下移动以及在楼层间停靠。通过此项目,我们可以强化对Java编程语言的理解,尤其是面向对象设计、多线程、事件驱动编程以及数据...
将呼叫和目标写入一个正文文件,然后程序读取这些呼叫和目标数据后可以在没有人工干预的情况下模拟电梯运行情况。其中一个呼叫/目标占一行,格式如下: <操作时间>[空格]<呼叫目标>[回车] 操作时间,表示呼叫请求的...
电梯模拟调度是一个典型的计算机科学问题,它涉及到数据结构和算法的应用。在这个课设中,我们主要探讨如何有效地管理和调度两部电梯,以满足一个高层建筑内居民的上下移动需求。这个任务的核心是设计一个高效的算法...
综上所述,这段C语言电梯模拟源代码不仅展示了如何使用图形库实现动态界面,还涵盖了数据结构管理、事件驱动编程、控制流逻辑等多个方面的知识,对于学习C语言和理解基础的软件工程原理具有一定的参考价值。
通过定义电梯状态、楼层信息和电梯信息的数据结构,以及利用EGG库创建交互式界面,我们可以实现一个功能丰富的电梯模拟器。这个模拟器不仅可以帮助学习者理解电梯系统的运作原理,也可以作为软件工程项目的实例,...
电梯模拟是计算机科学中一个经典的算法问题,通常用于教授并发控制、调度策略和状态机设计。在Java中实现电梯模拟,我们需要关注以下几个关键知识点: 1. **电梯模型**:首先,我们需要定义电梯的状态,如停在某一...
电梯模拟系统是一个典型的多线程控制问题,使用Java来实现能深入理解并发编程的概念和机制。在这个项目中,我们主要会涉及到以下几个核心知识点: 1. **Java基础**:首先,你需要具备基本的Java编程能力,了解类、...
在这个项目中,我们使用C或C++语言来构建一个电梯系统模型,旨在模拟真实世界中的电梯运行情况,包括上行、下行、停靠楼层、响应乘客请求等基本功能。下面将详细阐述电梯调度算法的相关知识点。 首先,我们要理解...
在这个场景中,我们关注的是一个基于52单片机的电梯模拟程序,它是一个通过软件模拟电梯的实际运行逻辑,以实现对硬件(如LED灯、按键和数码管)控制的项目。下面,我们将深入探讨这个程序所涉及的关键知识点。 1. ...
总的来说,操作系统中的电梯模拟实现是一个深入理解多任务调度、资源分配以及优化算法的实践案例。通过对“MyElevator”的研究,我们可以学习如何利用计算机科学的方法解决现实世界中的问题,并且提升我们的系统设计...
此外,考虑到实际的用户交互,我们需要一个简单的用户界面,即使是在命令行环境下,也能清楚地展示电梯的状态和用户的选择。这可能包括打印电梯的当前楼层、显示电梯的运动方向,以及接收用户输入的楼层选择。 总结...
8. **用户界面(UI)**:尽管描述中没有特别提及,但一个完整的电梯模拟可能还包括一个简单的UI,用于显示电梯当前状态和楼层。Windows Forms 或 WPF 可能用于创建这样的图形界面。 9. **调试技巧**:在VS2008中,...
然后,你需要创建一个模型来模拟电梯的移动、停靠和载客过程。这可能涉及到队列数据结构来存储请求,以及状态机的设计来跟踪电梯的状态。 在实现过程中,你可能需要用到以下编程概念: - **事件驱动编程**:电梯...
电梯模拟程序是一个经典的计算机科学问题,常常用于教授和实践面向对象编程的概念。在这个项目中,我们将探讨如何使用C++设计一个高效、灵活的电梯模拟系统。C++是一种强大的编程语言,支持面向对象编程,能够帮助...
在这个案例中,我们讨论的是一个使用VC++6.0编写的电梯运行模拟器。这个程序利用了数据结构和算法的知识,特别是对于状态机的设计和优化。 1. **VC++6.0**: Microsoft Visual C++ 6.0是一款经典的集成开发环境(IDE...
在本文中,我们将深入探讨如何利用Microsoft Foundation Classes (MFC) 框架来编写一个模拟电梯运行的程序。MFC 是微软为Windows应用程序开发提供的一套C++库,它封装了Windows API,使得开发者可以更高效地创建图形...