现在的位置: 首页 > 综合 > 正文

黑马程序员 – java基础项目 – 交通灯管理系统

2014年08月31日 ⁄ 综合 ⁄ 共 3882字 ⁄ 字号 评论关闭

-------android培训java培训、java基础学习技术博客、期待与您交流!
----------

1.1 项目需求分析

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
(1)异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由南向而来去往西向的车辆 ---- 左转车辆
由南向而来去往东向的车辆 ---- 右转车辆
(2)信号灯忽略黄灯,只考虑红灯和绿灯。
(3)应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
(4)具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
(5)每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
(6)随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
(7)不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

1.2 面向对象的分析和设计

1.路灯 Lamp
(1)从上图可见,十字路口中,总共12个方向的灯,每两个形成一组,一组灯同时变绿或变红,所以,
程序代码只需要控制每组灯中的一个灯即可。
S2N,N2S    
S2W,N2E
E2W,W2E
E2S,W2N
S2E,N2W
E2N,W2S
(2)上面最后两行的灯是虚拟的,由于从南向东和从西向北、以及它们的对应方向不受红绿灯的控制,
所以,可以假想它们总是绿灯。
(3)由于这些元素是固定不变的,因此可以采用枚举来表示路灯,也就是枚举中总共有12个Lamp元素。
同时,需要控制的枚举就是其中的四个元素。
S2N,S2W,E2W,E2S
(4)需要提供的方法
判断某个等是否为绿灯
某个灯变绿时,它对应方向的灯也要变绿
某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿
2. 路灯 Road
(1)每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。
(2)每条路线上随机增加新的车辆,增加到一个集合中保存。
(3)每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆
3. 路灯控制器 LampController
初始化时,让由南向北的灯变绿,然后每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿。
4. 路灯控制器 MainClass

(1)产生12个方向的路线
(2)产生整个交通灯系统

1.3 代码实现

//1. Lamp
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;
	}

	/*当前灯是否为绿*/	
	private boolean lighted;
	/*与当前灯同时为绿的对应方向*/	
	private String opposite;
	/*当前灯变红时下一个变绿的灯*/	
	private String next;
	public boolean isLighted(){
		return lighted;
	}
	
	/**
	 * 某个灯变绿时,它对应方向的灯也要变绿
	 */	
	public void light(){
		this.lighted = true;
		if(opposite != null){
			Lamp.valueOf(opposite).light();
		}
		System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");		
	}
	
	/**
	 * 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿
	 * @return 下一个要变绿的灯
	 */	
	public Lamp blackOut(){
		this.lighted = false;
		if(opposite != null){
			Lamp.valueOf(opposite).blackOut();
		}		
		
		Lamp nextLamp= null;
		if(next != null){
			nextLamp = Lamp.valueOf(next);
			System.out.println("绿灯从" + name() + "-------->切换为" + next);			
			nextLamp.light();
		}
		return nextLamp;
	}
}

//2. Road
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(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();
					}
					vechicles.add(Road.this.name + "_" + i);
				}				
			}			
		});
		
		//每隔一秒检查对应的灯是否为绿,是则放行一辆车		
		ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						if(vechicles.size()>0){
							boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
							if(lighted){
								System.out.println(vechicles.remove(0) + " is traversing !");
							}
						}
						
					}
				},
				1,
				1,
				TimeUnit.SECONDS);		
	}
}

//3. LampController
public class LampController {
	private Lamp currentLamp;
	
	public LampController(){
		//刚开始让由南向北的灯变绿;		
		currentLamp = Lamp.S2N;
		currentLamp.light();
		
		/*每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿*/		
		ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						System.out.println("来啊");
						currentLamp = currentLamp.blackOut();
					}
				},
				10,
				10,
				TimeUnit.SECONDS);
	}
}

//4. MainClass
public class MainClass {
	public static void main(String[] args) {
		
		/*产生12个方向的路线*/		
		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();
	}
}

总结:
该项目中主要使用的技术有枚举,线程池,以及框架类。比较关键的问题,在于理清路灯,路,路灯控制器之间的关系。
(1)路灯Lamp使用枚举来表示,其中提供了判断路灯是否为绿灯,将灯变绿,将灯变红灯的方法。
(2)路Road中需要有一个属性name来获取到对应的灯,需要一个集合类保存模拟路中存放的车辆,同时通过线程池,来实现随机给路中增加车辆,通过定时器,每秒钟移除一个元素来模拟路中通过的车辆。
(3)路灯控制器LampController中,通过定时器类初始化将南到北方向S2N的灯设置为绿灯,点亮。然后每隔10秒,切换到下一个灯。
(4)路灯控制器 MainClass产生12个方向的路线,产生整个交通灯系统。

-------
android培训
java培训、java基础学习技术博客、期待与您交流! ----------

抱歉!评论已关闭.