黑马程序员--交通灯案例学习

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


这个案例刚开始看时一头雾水,特别是路线看起来很多,非常干扰。后来跟着把代码敲了一遍,慢慢才理解解题思路以及代码的实现。

1.多画图分析

2.多写代码,即使不懂也可以跟着示例打

3.多注意各个类之间的关系,通过什么样的方式联系。


下面说说学习这个案例的总结

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

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

例如:

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

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

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

       。。。

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

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

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

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

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

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


案例中的实现分为两个核心部分

一是对灯的实现

二是对车辆的实现


车辆

虽然是车辆在行使,但我们真正要操作并不是车辆,因为要体现不是车的属性和功能如品牌、车速、代步功能等等。要体现的只是车的出现与消失,所以车辆是被当作数据来处理的。示例中定义了Road类来操作车辆。

每条路线上都会出现多辆车,路线上要随机增加新的车,在灯绿期间还要每秒钟减少一辆车。

每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。

每条路线上随机增加新的车辆,增加到一个集合中保存。

<span style="font-size:14px;">public class Road {
	private List<String> vechicles = new ArrayList<String>();
	
	private String name = null;
	
	public Road(String name) {
		this.name = name;
	//这个线程实现了车辆的随机生成,把生成的车存入集合
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
			for(int i=1; i<1000; i++) {
				try {
					vechicles.add(Road.this.name+"__"+i);
					Thread.sleep((new Random().nextInt(10)+1)*100);
				} 
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}	
			}
		});
		//这个线程实现的是车辆通行与停止,也是车辆与灯系统连接的地方。
		Executors.newScheduledThreadPool(1).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);
	}
}
</span></span></span></span>




灯系统

这里主要的问题是如何划分各种线路的灯,能不能找到规律,能不能找到与车辆系统的连接点是关键

画图非常有利于理解和分析问题


总共有12条路线,所以,系统中总共要产生12个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方式,故假设出有四个右拐弯的灯,只是这些灯为常亮状态,即永远不变黑。

除了右拐弯方向的其他8条路线的灯,它们是两两成对的,可以归为4组,所以,在编程处理时,只要从这4组中各取出一个灯,对这4个灯依次轮询变亮,与这4个灯方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象的变亮和变黑方法中,将对应方向的灯也变亮和变黑。每个灯变黑时,都伴随者下一个灯的变亮,Lamp类中还用一个变量来记住自己的下一个灯。

无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类改用枚举来做显然具有很大的方便性,永远都只有代表12个方向的灯的实例对象。枚举的应用很有力量,要理解如何运用。

<span style="font-size:18px;">public void light() 
public Lamp blackOut()</span>
枚举中对外提供了两个方法,就像给灯装了开关一样。那么下一步就是设置让它何时开,何时关了。

<span style="font-size:14px;">ublic class LampController {
	private Lamp currentLamp;
	
	public LampController() {
		currentLamp = Lamp.S2N;
		currentLamp.light();
		
		//通过定时的日程线程,每隔设置的时间就会调用了一次.blackOut()方法,绿灯就得到一次切换
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					public void run() {
						currentLamp = currentLamp.blackOut();
					}
				}, 
				2, 
				2, 
				TimeUnit.SECONDS);
	}
}</span>


最后的主函数只要创建12个路线的实例以及一个控制器的对象即可。



----------------------  ASP.Net+Android+IOS开发 .Net培训 、期待与您交流! ----------------------







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值