模拟交通灯管理系统

    技术2022-05-20  53

    需求:模拟实现十字路口的交通灯,

    1、信号灯忽略黄灯,只考虑红灯和绿灯;

    2、直线、左转车辆受信号灯控制,右转车辆不受信号灯控制

    3、南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

     

    十字路口的模拟图:

    根据需求我们需要抽象的类有:信号灯、信号灯控制器、路。

     

    从十字路口的模拟图,可以看出南和北的路线相对应、东和西的路线相对应,这样我们只要考虑两个方向上的信号灯就可以了。假设我们只考虑由南向北和由东向西方向上的信号灯。

    1、先设计信号灯:首先考虑灯的属性,灯亮与否;灯当前在那个方向上;当前灯灭了后下一个灯该在哪个方向上;灯还需要用来控制当前灯的变化方法。

    假如我们用普通类来设计这个灯,可能会设计成这样:

    public class Lamp { private boolean lighted; private Lamp opposite; private Lamp next;  public Lamp(Lamp opposite,Lamp next,boolean lighted){  this.opposite = opposite;  this.next = next;  this.lighted = lighted; } /**  * 当前灯的状态  * @return  */ public boolean isLighted(){  return lighted; }  public void light(){  lighted = true;  if(opposite != null){   opposite.light();  } }  public Lamp back(){  lighted = false;  if(opposite != null){   opposite.back();  }    Lamp nextLamp = null;  if(next != null){   next.light();   nextLamp = next;  }  return nextLamp; }}

     若设计成这样,当我们在创建这个类的时候会发现这个类创建不出来,因为当创建A时需要先创建B和C,而创建B又需要先创建D等等,所有我们考虑用枚举来做。

    public enum Lamp {

    /*每个枚举元素各表示一个方向的控制灯*/  S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false), /*下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!*/ N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false), /*由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯*/ S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);  private Lamp(String opposite,String next,boolean lighted){  this.opposite = opposite;  this.next = next;  this.lighted = lighted; }

     

    其他合上面的方法一样

    }

    灯设计好了,现在设计灯的控制器

    2、设计信号灯的控制器:控制器主要作用是控制每隔多久灯变化一次。考虑到控制器肯能被多个路口调用,且在整个系统中又是独立的,故将其设计成单例。

    public class LampContraller { private Lamp currLamp; private static LampContraller instance = new LampContraller(); private LampContraller(){  Lamp opposite = new Lamp(null,null,false);  Lamp next = new Lamp(null,null,false);  currLamp = new Lamp(opposite,next,false);  currLamp.light(); }  public static LampContraller getInstance(){  return instance; } public void contrallCode(){  ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);  timer.scheduleAtFixedRate(    new Runnable(){     public  void run(){      currLamp = currLamp.back();    }    },    10,    10,    TimeUnit.SECONDS); }}接下来就剩下路的设计了

    3、首先要考虑的是车是在路上的,所有需要有个存储车的空间,其次是这个路的名称;还有车辆到了当前路口和车辆离开当前路口的方法。代码如下:

    public class Road { private List<String> cars = new ArrayList<String>(); private String roadName = "";  public Road(String name){  this.roadName = name;  carOnRoad();  carMoveRoad(); }  /**  * 车到了路口  */ private void carOnRoad(){  Executors.newSingleThreadExecutor().execute(new Runnable(){   public void run(){    for(int i=1;i<1000;i++){     try {      Thread.sleep((new Random().nextInt(10) + 1) * 1000);     } catch (InterruptedException e) {      e.printStackTrace();     }     cars.add("车辆"+Road.this.roadName + "_" + i);     System.out.println("车辆"+Road.this.roadName + "_" + i+"到了路上");    }    }  }); } /**  * 车开走了  */ private void carMoveRoad(){  Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable(){   public void run(){    if(cars.size() > 0){     boolean lampStatus = false;     if(lampStatus){      System.out.println(cars.remove(0)+"离开了路上");     }    }   }  }, 1, 1, TimeUnit.SECONDS); }}

     

    好了设计完成。这里需要注意的是不要被方向给绕进去了,考虑使用枚举。


    最新回复(0)