【黑马程序员】交通灯管理系统_学习笔记

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


首次接触这种比较大的工程,或者说是系统,整个过程还是学到了很多东西的。


首先是拿到项目的思路问题,一直苦于不知道从0开始如何下手,看了张孝祥老师的视频之后真是受益良多。

1、张老师说了,拿到项目先画图,不要空想,多画图是有好处的,事实证明,画图能使思路更清晰,思考也能更加直观,下面是跟着老师画的交通灯管理系统的图。


从图中可以分析出来,需要走的路线一共有12条,这也是之后在主方法中需要new出来的对象。

2、对参与事物进行分析与分类,对事物的本质进行分析。该项目中,需要分析的有四个事物,分别是灯、灯的控制器、汽车、路。

灯:4个路口12个灯,不允许new对象,用枚举(往其中写十二个元素),保证只有12个对象,不能单独创建对象,只有四个灯有逻辑,其他灯跟随这4个灯变化。

在这里,我们不考虑黄灯的情况,只考虑简单的红绿两种灯的情况。
灯的控制器:一个灯绿了,对面的灯跟着绿了,并且返回给下一个灯,下一个灯就红了。
汽车:灯变绿,前面没有车,才能走,是否有车要问路。不需要研究车的属性和走的过程,所以汽车是字符串而不是对象。
路:12条路线,一个集合,集合中很多车,有增加车辆和减少车辆的方法,变绿灯了则取走最前端的一个车。

以上是对参与事物的分析,于是接下来,便可以根据图和各事物的分析进行代码的编写了。

3、写代码的过程中,命名很重要,同时,需要严谨的进行,否则时候检查会增加很多工作量。

package cn.itheima.interview.traffic;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Road {
	List<String> vechicles = new ArrayList<String>();
	
	private String name = null;
	public Road(String name)
	{
		this.name = name;
		
		ExecutorService pool = Executors.newSingleThreadExecutor();//Executors线程管理工具
										//newSingleThreadExecutor()只有单个线程的线程池
		pool.execute(new Runnable(){ //实现了一个Runnable对象
			public void run(){
				for(int i=1; i<1000; i++){
					try {
						Thread.sleep((new Random().nextInt(10)+1)*1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					vechicles.add(Road.this.name + "_" + i);
				}			
			}		
		});	
		
		//定时器
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//调度池
		timer.scheduleAtFixedRate(
				new Runnable() {
					
					@Override
					public void run() {
						if(vechicles.size()>0)
						{
							boolean light = Lamp.valueOf(Road.this.name).isGreen();
							if(light)
								System.out.println(vechicles.remove(0)+" is traversing!");
						}
						
					}
				},
				1, 
				1, 
				TimeUnit.SECONDS
				);
	
	}
}

在这段路的代码中,我们讲交通工具作为一个字符串属性存在了集合中,并且,定义了一个定时器,指定灯换了之后开始的时间,并且这个时间是用额外的线程进行操作。

package cn.itheima.interview.traffic;

/*
 * S2N,S2W,E2W,E2S,
	N2S,N2E,W2E,W2N,
	S2E,E2N,N2W,W2S;
 * 
 * 
 * */
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 light)
	{
		this.opposite = opposite;
		this.next = next;
		this.light = light;
	}
	
	private boolean light;
	private String opposite;
	private String next;
	
	public boolean isGreen(){
		return light;
	}
	
	public void setGreen()
	{
		this.light = true;
		if(opposite!=null)
			Lamp.valueOf(opposite).setGreen();
		System.out.println(name() + " is green , 接下来有6个方向有汽车穿过");
	}
	
	public Lamp setRed()
	{
		this.light = false;
		if(opposite!=null)
			Lamp.valueOf(opposite).setRed();
		
		
		Lamp nextLamp = null;
		
		if(next != null){
			nextLamp = Lamp.valueOf(next);
			System.out.println("绿灯从" + name() + "---------->" + next);
			nextLamp.setGreen();
		}
		System.out.println(name() + " is red");

		return nextLamp;
	}
}
这段代码是灯的枚举,因为考虑到灯整条线路只有12种情况,为了限定好数目并不允许额外生成对象,所以使用枚举这一项技术。

以方向的方式定义枚举的元素,并且,其中拥有现在的亮灯方向,下一个亮灯方向,以及现在的亮灯情况,而且,其中还写有setGreen和setRed方法,用于设置灯的状态,同时在setRed中设置返回值给下一个灯。

package cn.itheima.interview.traffic;

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

public class LampController {
	private Lamp currentLamp;
	
	public LampController(){
		currentLamp = Lamp.S2N;
		currentLamp.setGreen();
		
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable() {
					
					@Override
					public void run() {
						currentLamp = currentLamp.setRed();
						
					}
				}, 
				10, 
				10, 
				TimeUnit.SECONDS);
		
		
	}

}

这是灯的控制器,首先定义一个灯的现在状态,并且构造函数默认S2N灯是绿的,下面提供定时器,以10秒为间隔将绿灯变红。

public class MainClass {
	public static void main(String[] args){
		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();
	}

}

最后是主函数的代码,因为12个对象很多,所以不考虑 一个个去new,于是想到先将这些字符串以数组的形式储存起来,然后用for循环定义,12个对象都建立之后就调用灯的管理器,开始进行代码的检验了。


通过这次张孝祥老师的交通灯视频,我了解了拿到题目或者项目之后首先该做的是什么,另外还对面向对象的思想又理解了一些,这对我以后的学习非常有帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值