黑马程序员之Java--交通灯管理系统需求分析及总结

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

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 

Ø  异步随机生成按照各个路线行驶的车辆。

例如: 由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。 

Ø  信号灯忽略黄灯,只考虑红灯和绿灯。 

Ø  应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。 

Ø  具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

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

Ø  每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。 

Ø  随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。 

Ø  不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


根据上述需求,先画个图,了解下方向

从图中分析下:
总共有12条路线,为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制灯可以假设称为常绿状态,另外,其他的8条线路是两两成对的,可以归为4组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

面向对象分析与设计
​1、每条路线都会出现很多车,路线上要随机增加很多车,在灯绿期间还要每秒减少一辆车
       那么就设计一个Road类,每个Road对象就是一条路线,总共12条,故系统中要产生12 个实例对象
      每条路线上要随机增加车辆,故需要一个队列集合存储车辆,先来的车辆,先开走
      路线上会定期每秒检查对应的灯是否绿,是则从集合中移除一辆车,表示穿过路口。这里就有个定时器,定时操作
2、交通灯都有各自的状态,灯绿或灯红,且有12个方向的灯
    那么就设计一个Lamp类,表示交通灯,有个状态lighted,值为true或false,表示灯绿或灯红。灯还有个变绿和变红的方法 总共有 12 条路线,所以,系统中总共要产生 12 个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方     法,故假设出有四个 右拐弯的灯,只是这些灯为常亮状态,即永远不变黑。    除了右拐弯方向的其他 8 条路线的灯,它们是两两成对的,可以归为 4 组,所以,在编程处理时,只要从这 4 组中各取出一个灯,对这 4 个灯依次轮询  变亮,与这 4 个灯方向对应的灯则随之一同变化,因此 Lamp 类中要有一个变量来记住自己相反方向的灯,在一个 Lamp 对象的变亮和变黑方法中,将 对应 方向的灯也变亮和变。每个灯变黑时,都伴随者下一个灯的变亮, Lamp 类中还用一个变量来记住自己的下一个灯。
  无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以 Lamp 类改用枚举来做显然具有很大的方便,永远都只有代 12 个方向的灯的实例对象。  需要个交通灯控制器,控制灯定时更换状态

于是就有了以下类:
1、Road类:表示路线,路线上有很多车辆,使用队列集合存储
package com.heima.traffic;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 路线:每条路线都有随机的车辆,每次绿灯行驶
 * @author Administrator
 *
 */
public class Road {
	//队列,存储车辆使用
	private Quere<String> list = null;
	//路线方向
	private String name ;
	public Road(String name){
		this.name  =name;
		list = new Quere<>();
		
		//定时模拟车辆在路上
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			
			@Override
			public void run() {
				for(int i=1;i<1000;i++){
					try {
						//从1秒到10秒中随机产生再乘以1秒,也就是1秒到10秒
						Thread.sleep((new Random().nextInt(10)+1)*1000);
					} catch (InterruptedException e) { 
						e.printStackTrace();
					}
					list.add(Road.this.name+"_"+i); //存储车辆
				}				
			}
		});
		
		//每秒检查当前路线上的灯,绿灯就通车
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					
					@Override
					public void run() {
						//获取当前路线上的灯
						Lamp currentLamp = Lamp.valueOf(Road.this.name);
						//判断灯是否绿
						if(currentLamp.isLight()&&!list.isEmpty()){
							//开走一辆车
							String car = list.remove();
							System.out.println(car+" is traffic ……");
						}						
					}
				},
				1,
				1, 
				TimeUnit.SECONDS
			);
	}
}

2、Quere类:表示队列,存储车辆的集合
package com.heima.traffic;

import java.util.LinkedList;

/**
 * 队列,存储车辆的集合类,先进先出
 * @author Administrator
 *
 */
public class Quere<T> {

	private LinkedList<T>  list = null;
	public Quere(){
		list = new LinkedList<>();
	}
	
	public void add(T t){
		list.addFirst(t);
	}
	
	public T remove(){
		return list.removeLast();
	}
	
	public boolean isEmpty(){
		return list.isEmpty();
	}
}


3、Lamp:表示交通灯,有变亮和变黑的方法,变黑后要返回下个变亮的灯,共有12个灯,除去右转的常绿灯,还有8个灯,共4组
/**
 * 交通灯,共12个,右转的有4个是常绿,还有8个是相对应的,也就是有4组灯
 * @author Administrator
 *
 */
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 String oppive;
	//下一个灯
	private String nextLamp;
	//灯的状态
	private boolean lighted = false; 	
	private Lamp(String oppive ,String nextLamp,boolean lighted){		
		this.oppive = oppive;
		this.nextLamp = nextLamp;
		this.lighted =lighted;
	}
	
	/**
	 * 是否绿灯
	 * @return
	 */
	public boolean isLight(){
		return lighted;
	}
	
	/**
	 * 设置绿灯
	 */
	public void light(){
		this.lighted = true;
		if(oppive!=null){
			 Lamp.valueOf(oppive).light();		 
		}
		System.out.println(name()+"变为绿灯");
	}
	
	/**
	 * 设置红灯,返回下一个绿灯
	 * @return
	 */
	public Lamp blaceout(){
		this.lighted = false;		
		if(oppive!=null){
		  Lamp.valueOf(oppive).blaceout(); 
		}
		Lamp nextlam = null;
		if(nextLamp!=null){
			nextlam = Lamp.valueOf(nextLamp);
			nextlam.light();	
			System.out.println("绿灯由"+name()+"转为"+nextLamp);
		}
		return nextlam;
	}

}

4、LampController: 表示交通灯控制器,定时控制灯的状态
package com.heima.traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * 交通灯控制器
 * @author Administrator
 *
 */
public class LampController {
	private Lamp currentlamp;
	private LampController(Lamp lamp){
		this.currentlamp = lamp;
		this.currentlamp.light();
	}
	
	/**
	 * 控制交通灯变换状态,每隔10秒更换一次
	 */
	public void start(){		
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {					
					@Override
					public void run() {	
						//判断灯是否绿
						if(currentlamp.isLight()){
							//设置灯为红且返回下一个绿灯
							currentlamp = currentlamp.blaceout();
						}
					}
				},
				10, 
				10, 
				TimeUnit.SECONDS
				);
		
	}
	
	private static LampController instance = new LampController(Lamp.S2N);
	public static LampController getInstance(){		
		return instance;
	}
}

5、测试类
package com.heima.traffic;

public class MainClass {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] lamps = {
				"S2N","S2W","E2W","E2S",
				"N2S","N2E","W2E","W2N",
				"S2E","E2N","N2W","W2S"				
		};
		
		//循环构造出12条路线
		for(int i = 0;i< lamps.length;i++){			
			new Road(lamps[i]);
		}	
		//控制器开始运行
		 LampController.getInstance().start();
	}

}

视频中张老师在Road类中用ArrayList集合存储车辆,我单独把存储集合的类封装成队列,队列具有先进先出,即排在前面的车先走,不用判断前面是否还有车


------- android培训java培训、期待与您交流! ----------
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值