模拟交通灯管理系统

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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值