美文网首页
设计电梯系统

设计电梯系统

作者: 放开那个BUG | 来源:发表于2022-04-30 20:51 被阅读0次

1、前言

电梯系统可以只采用一个队列,然后可以决定请求的方向:

  • 如果无请求,则根据请求的楼层与当前楼层相比,决定是 UP 还是 Down
  • 如果电梯方向为 UP,且当前楼层之上无请求,则根据请求的楼层与当前楼层相比,决定是 UP 还是 Down
  • 如果电梯方向为 Down,且当前楼层之下无请求,则根据请求的楼层与当前楼层相比,决定是 UP 还是 Down

电梯系统应该也算是一个管理类系统,不管是管理类还是预定类、实物类,都是非常经典的主体、input、output 形式。

那么主体肯定是一个电梯系统,input 是用户输入的 Request,output 是电梯(控制哪个电梯服务,为了简单这里使用一部电梯)。而且我们只考虑人在电梯里按按钮的情况,不考虑外部按按钮的情况。

2、设计

那么很清楚的能想到有这几个类:Request、EvelatorSystem、Evelator、Status

Request 有 level 属性,表示要去的楼层。

Status 是个枚举,标识电梯的方向,是 Up、Down 还是 Idle。

EvelatorSystem 主要持有 Evelator 的引用,它处理请求相当于 Evelator 处理请求。

Evelator 是整个电梯系统的核心类,主要有以下几个属性和方法:


Evelator 类图

属性:

  • upStops:向上需要去的楼层
  • downStops:向下需要去的楼层
  • currentLevel:电梯现在所在的楼层
  • status:电梯现在的方向

方法:

  • handlerInternalRequest(Request request):根据现在的方向来决定是向下还是向上
  • openGate():在第几层开门
  • closeGate():在第几层关门,需要清理一下状态
  • noneRequests(boolean[] stops):是否无任何请求

首先,我们假设先摁了 3、6层,到达3层后又摁了2层,如果把2放到一个队列里,那么不管取最大还是最小都不行。所以分为了两个队列,分布放向上或者向下要去的楼层。当然是根据条件判断的。

3、代码

ElevatorSystem:

/**
 * @author xushu
 * @create 4/30/22 5:39 PM
 * @desc 不要引入外部按上下按钮,会使你的系统变得复杂。只考虑人在电梯按按钮
 */
public class ElevatorSystem {

    private Elevator elevator;

    public ElevatorSystem(Elevator elevator) {
        this.elevator = elevator;
    }

    public void handlerRequest(Request request) throws Exception {
        this.elevator.handlerInternalRequest(request);
    }

    public void processRequests() throws Exception {
        this.elevator.handlerInternalRequest(new Request(8));
        this.elevator.handlerInternalRequest(new Request(3));
        this.elevator.handlerInternalRequest(new Request(11));
        Random random = new Random();
        while (true){
            if(elevator.isSomeThingLeftInStops()){
                elevator.openGate();
                elevator.closeGate();

                this.elevator.handlerInternalRequest(new Request(random.nextInt(12) + 1));
            }
        }
    }

    public static void main(String[] args) throws Exception {
        ElevatorSystem elevatorSystem = new ElevatorSystem(new Elevator(12));

        elevatorSystem.processRequests();
    }
}

Request:

public class Request {

    protected int level;

    public Request(int level) {
        this.level = level;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }
}

Status:

/**
 * @author xushu
 * @create 4/30/22 6:01 PM
 * @desc 电梯的方向
 */
public enum  Status {
    UP,
    DOWN,
    IDLE
}

Elevator(两个队列的):

public class Elevator {

    /**
     * 向上需要去的楼层
     */
    private boolean[] upStops;

    /**
     * 向下需要去的楼层
     */
    private boolean[] downStops;

    /**
     * 电梯现在所在的楼层
     */
    private int currentLevel;

    /**
     * 电梯现在的方向
     */
    private Status status;

    public Elevator(int n) {
        this.upStops = new boolean[n];
        this.downStops = new boolean[n];
        this.currentLevel = 0;
        this.status = Status.IDLE;
    }

    public void handlerInternalRequest(Request request) throws Exception {
        if(request.level <= 0 || request.level > upStops.length){
            throw new Exception("楼层不合法");
        }

        // 无论电梯向上还是向下运行,只要你的楼层比当前楼层大,那就放入 up 队列,否则放入 down 队列
        if(request.level - (currentLevel + 1) <= 0){
            downStops[request.level - 1] = true;
            if(noneRequests(upStops)){
                status = Status.DOWN;
            }
        }else {
            upStops[request.level - 1] = true;
            if(noneRequests(downStops)){
                status = Status.UP;
            }
        }
    }

    public void openGate(){
        switch (status){
            case UP:
                for (int i = currentLevel; i < upStops.length; i++) {
                    if(upStops[i]) {
                        upStops[i]  = false;
                        currentLevel = i;
                        break;
                    }
                }
                break;
            case DOWN:
                for(int i = currentLevel; i >= 0; i--) {
                    if(downStops[i]) {
                        downStops[i] = false;
                        currentLevel = i;
                        break;
                    }
                }
                break;
        }
        System.out.println("方向是:" + status.name() + ", 楼层是:" + (currentLevel + 1) +  "开门!");
    }

    public void closeGate(){
        System.out.println("方向是:" + status.name() + ", 楼层是:" + (currentLevel + 1) + "关门!");

        if(noneRequests(upStops) && noneRequests(downStops)){
            status = Status.IDLE;
        }else if(noneRequests(upStops) && !noneRequests(downStops)){
            status = Status.DOWN;
        }else {
            status = Status.UP;
        }
    }

    public boolean noneRequests(boolean[] stops){
        for (int i = 0; i < stops.length; i++) {
            if(stops[i]){
                return false;
            }
        }
        return true;
    }

    public boolean isSomeThingLeftInStops(){
        for (int i = 0; i < upStops.length; i++) {
            if(upStops[i] || downStops[i]){
                return true;
            }
        }
        return false;
    }
}

Elevator(一个队列的):

public class Elevator {

    /**
     * 要停的楼层
     */
    private boolean[] stops;

    /**
     * 电梯现在所在的楼层
     */
    private int currentLevel;

    /**
     * 电梯现在的方向
     */
    private Status status;

    public Elevator(int n) {
        this.stops = new boolean[n];
        this.currentLevel = 0;
        this.status = Status.IDLE;
    }

    public void handlerInternalRequest(Request request) throws Exception {
        if(request.level <= 0 || request.level > stops.length){
            throw new Exception("楼层不合法");
        }

        // 如果无请求,只要你的楼层比当前楼层大,电梯方向向上;否则向下
        // 如果电梯方向向上,且向上无请求,则根据请求决定电梯方向
        // 如果电梯方向向下,且向下无请求,则根据请求决定电梯方向
        if(noneRequests(stops) || (status.equals(Status.UP) && noUpRequests(stops)) || (status.equals(Status.DOWN) && noDownRequests(stops))){
            status = request.level - (currentLevel + 1) <= 0 ? Status.DOWN : Status.UP;
        }
        stops[request.level - 1] = true;
    }

    public void openGate(){
        switch (status){
            case UP:
                for (int i = currentLevel; i < stops.length; i++) {
                    if(stops[i]) {
                        stops[i]  = false;
                        currentLevel = i;
                        break;
                    }
                }
                break;
            case DOWN:
                for(int i = currentLevel; i >= 0; i--) {
                    if(stops[i]) {
                        stops[i] = false;
                        currentLevel = i;
                        break;
                    }
                }
                break;
        }
        System.out.println("方向是:" + status.name() + ", 楼层是:" + (currentLevel + 1) +  "开门!");
    }

    public void closeGate(){
        System.out.println("方向是:" + status.name() + ", 楼层是:" + (currentLevel + 1) + "关门!");

        if(noneRequests(stops)){
            status = Status.IDLE;
        }
    }

    public boolean noneRequests(boolean[] stops){
        for (int i = 0; i < stops.length; i++) {
            if(stops[i]){
                return false;
            }
        }
        return true;
    }

    public boolean noUpRequests(boolean[] stops){
        for (int i = currentLevel; i < stops.length; i++) {
            if(stops[i]){
                return false;
            }
        }
        return true;
    }

    public boolean noDownRequests(boolean[] stops){
        for (int i = currentLevel; i >= 0; i--) {
            if(stops[i]){
                return false;
            }
        }
        return true;
    }

    public boolean isSomeThingLeftInStops(){
        for (int i = 0; i < stops.length; i++) {
            if(stops[i] || stops[i]){
                return true;
            }
        }
        return false;
    }
}

相关文章

  • 设计电梯系统

    1、前言 电梯系统可以只采用一个队列,然后可以决定请求的方向: 如果无请求,则根据请求的楼层与当前楼层相比,决定是...

  • 程序猿在等电梯时都在想什么?

    等这么久了,电梯怎么还没来???一定是电梯调度有问题!那就让我给它设计一个电梯调度算法。 电梯调度与操作系统中的磁...

  • 理性看生活中的电梯

    一、引子 最近偶然刷到b站柴知道分享的关于电梯的有趣视频。 不仅涉及计算机学科中的scan算法以及电梯调度系统设计...

  • 电梯设计(2)——电梯局部设计体验

    这篇文章谈谈电梯的局部设计及电梯算法,顺便列举几个自己在日常生活中观察到的例子。 电梯局部设计打算从电梯内...

  • Java模拟电梯系统

    介绍: 用Java编写对的模拟电梯上下楼。 运行截图: 初始化界面 电梯进行上楼,输入3 5 -1 电梯下楼,输入...

  • AI+区块链电梯“智能到家”

    电梯作为特种安全设备,在确保电梯按安全标准设计与制造,确保电梯运行与使用安全之外。还需要做些什么? 某品牌电梯始终...

  • 系统设计(八)

    1. 系统设计 什么是系统设计 系统设计需要掌握哪些知识 如何设计和实现一个后端系统服务的设计 系统设计是一个初高...

  • 打造企业绝对优势之机会

    根据袁国顺老师免费系统课程整理生发 以一个案例来看如何盘活电梯工厂的,电梯工厂生产积压了不少电梯,电梯质量很...

  • 默纳克电梯如何设计出别致的别墅电梯

    默纳克电梯如何设计出别致的别墅电梯 别墅电梯正确定义是家用电梯。即安装在私人住宅中,仅供单一家庭成员使用的电梯。它...

  • 设计系统 Design Systems

    什么是设计系统?为什么要使用设计系统?如何建立设计体统?设计系统有没有弊端?有哪些相关的资源? 什么是设计系统? ...

网友评论

      本文标题:设计电梯系统

      本文链接:https://www.haomeiwen.com/subject/sysjyrtx.html