黑马程序员-交通灯管理系统

---------------------- Android培训java培训、期待与您交流! ----------------------

一、分析交通路线。

以路口为准,每个方向来车看成一组,共东、西、南、北4组车辆。
每组车辆都有3种行驶路线:向左、向右、直行,即:十字路口共12种行驶路线(如上图)。

为统一编程模型,可以假设每条线路都有红路灯进行控制,右转弯的
4条路线的控制灯可以假设称为常绿灯。除去右转弯路线以外还有8条路线的灯,
它们两两成对,(南北方向两个直行、两个左转;东西方向两个直行、两个左转
)共分成4组。每组两个信号灯的状态是一致的。所以只考虑每组中一种路线即可。

二、面向对象的分析与设计。
面向对象设计把握一个重要经验:谁拥有数据,谁就对外提供操作这些数据的方法。
初步分析项目中可以抽象为类的事物有:路线、交通灯、交通灯控制系统、车。
详细分析后发现车的行驶受到交通灯的限制,还要看前方是否有车辆即访问路线对象
的数据。路中存储着车辆的集合,显然应该有增加减少车辆的方法。题目中不要求体现
车辆的移动过程,只是捕捉路上减少一辆车的过程。所以车不需要单独设计一个类,用
一个字符串表示就可以了。
1,路线类(Road):
(1:设计一个Road类来表示路线,每个Road对象代表一条路线,共12条路线,即要产生
12个Road实例对象。
(2:每个路线增加另一个集合用来存储线路上的车辆。
(3:每条路线每隔一秒都会检查本路线的灯是否为绿,是则将被路线保存车的集合的
第一辆车移除,即表示车辆穿过路口。

public class Road{
 private List<String> vechicles = new ArrayList<String>();
 
 private String name = null; //路线名称
 public Road(String name){
 this.name = name;
 
 ExecutorService pool = Executors.newSingleThreadExecutor();//另起一个线程用于随机产生车辆。
 pool.execute(newRunnable(){
  for(int i=0; i<1000; i++){
   try{
    Thread.sleep((new Random().newInt(10)+1)*1000); //1~10秒随机驶来一辆车
   }catch(InterryptedException e){
    e.printStackTrace();
   }
   vechicles.add(Road.this.name + "-"+i);//内部类访问外部类成员变量
  }
 });

 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //创建大小为1的线程池作为定时器。
 timer.scheduleAtFixedRate(
             new Runnable(){
               public void run(){
                if(vechicles.size()>0){
                //调用Lamp枚举类valueOf方法得到当前路线上的灯。
                 boolean lighted = Lamp.valueOf(Road.this.name);
                 if(lighted){
                  System.out.println(vechicles.remove(0) + "is traversing !");//移除第一个元素表示开走第一辆车。
                 }
                }
               },//要执行的任务。
               1,//一秒后开始执行。
               1,//每隔一秒执行一次。
               TimeUnit.SECONDS);//参数的时间单位。

 }
 
}

 

2,交通灯类(Lamp):
(1:设计一个Lamp类表示一个交通灯,每个交通等都维护一个状态:亮(绿)后不亮(红),
交通灯要有变亮变黑的方法,并且返回自己的状态。因为该类中只有12个固定实例,所以想到了用枚举类来描述路线更优。
(2:12条路线则有12个交通灯,因为右转弯不受灯限制,为了保证程序采用统一处理方式,
则让右转灯常亮即可。
(3:除去右路线还有8条路线的灯,它们两两成对,(南北方向两个直行、两个左转;东西方向两个直行、两个左转
)共分成4组。每组两个信号灯的状态是一致的。

public enum Lamp{
 S2N("N2S","S2W,false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
  //被关联的灯不在有关联灯否则light()与blackOut()方法会进入死循环.
 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);
 
 pivate Lamp(String opposite,String next,boolean lighted){ //关联同组的灯,下一个灯,设置灯当前状态。
  this.opposite = opposite;
  this.next = next;
  this.lighted = lighted;
 }
 private boolean lighted;
 private String opposite;  //定义了String类型而没有直接定义Lamp类型,是因为对象没有被创建之前不能作为参数。
 private String next;
 
 public boolean isLighted(){  //判断灯是否是亮的
  return lighted;
 } 
 public void light(){ //点亮当前灯。
 this.lighted = true;
  if(opposite != null){ //如果有关联灯则一起点亮.
   Lamp.valueOf(opposite).light();
  }
 }
 public void blackOut(){ //关闭当前灯(亮红灯)。
  this.lighted = false;
  if(opposite != null){ //如果有关联灯则一起关掉。
   Lamp.valueOf(opposite).blackOut();
  }
  Lamp nextLamp = null;
  if(next != null){    
    nextLamp = Lamp.valueOf(next);//获取下一个灯的实例对象
  	nextLamp.light();
  }
  return nextLamp; //当灭掉当前灯点亮当下一个灯后blackOut方法返回下一个灯,为控制器类使用。
 }
 
}


 

3,交通灯控制器与主方法类:

public class LampController{
 private Lamp currentLamp;
 
 public LampController(){
 //南开往北的路线上的灯先亮
  currentLamp = Lamp.S2N; 
  currentLamp.light(); 
  
  ScheduledExecutorService timer = new Executors.newScheduledThreadPool(1);//创建大小为1的线程池。
  timer.scheduleAtFixedRate(new Runnable(){
   public void run(){
    currentLamp = currentLamp.blackOut(); //每过十秒当前灯变红。
   }
  },
  10,//10秒后开始执行。
  10,//之后每10秒执行一次。
  TimeUnit.SECONDS);//时间单位为秒。
 }
}
public class mainClass{
 public static void main(String[] args){
 //用一个字符串数组存储将要建立的“Road对象的名称,便于建立对象。
  String[] directions = new String[]{
   "S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
  };
  for(int i=0; i<directions.length; i++){
   new Road(directions[i]);
  }
  new LampController();//启动交通灯控制器。
 }
}


 

---------------------- Android培训java培训、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值