[one_demo_15]模拟交通灯管理系统

项目需求

模拟实现十字路口的交通灯管理系统逻辑。

  1. 异步随机产生各个路线上行走的车辆。例如,由南向北的直行车辆,由南向西的左转车辆,由南向东的右转车辆。
  2. 信号灯忽略黄灯,只考虑红灯和绿灯。
  3. 需考虑左转车辆受信号灯控制,右转车辆不受信号灯控制。
  4. 信号灯的具体的控制逻辑与现实中的情况一致,不考虑特殊情况。南北向车辆和东西向车辆交替放行,同方向车辆,先放行直行车辆再放行左转车辆。
  5. 每辆车过路口的时间为1秒,可以使用sleep模拟。
  6. 随机生成车辆时间和交通灯切换时间自定义。

需求分析

为了便于分析,可以画十字路口的图帮助分析。

面向对象分析和设计

1,分析十字路口图,两条路,4个大方向,每个大方向产生3个细分方向,一共有12个方向,那么就需要12个灯。车辆在线路上行驶,车辆的产生和通过由线路控制。

2,系统涉及到3个类,交通灯,线路,交通灯管理器。

3,线路类,12个方向,需要12个线路对象,每个线路对象有一个name表示这个线路的方向,由于车辆不需要考察车的属性和车本身的方法,所以,线路中的车以字符串表示,车的增加和通过路口就使用一个集合模拟队列的先进先出实现。每条线路每隔一秒检查本线路的灯是否为绿,如果绿灯,则将线路车辆集合中的第一辆放行过路口。

4,交通灯类,一共有12个灯是固定的,采用枚举类型比较方便,12个方向的灯,枚举类型设置判断灯是否绿的方法,将红灯转绿灯的方法,将绿转为红灯的方法,本灯下个灯的方法和设置每个枚举属性值的构造方法。对于12个方向灯,分析其特点,其中4个右转的方向是不受灯控制的,为了便于编程,将这个4个灯设置为常绿;另外8组方向,当一个方向绿时,其反方向必然也为绿,可以将这8组,看作两个4组,其中一组受到另外一组的控制,需要一个反方向变量来表示器反方向,拿出来其中的一个4组方向,定时对这4个方向做轮询,比如一个方向变红后,那么其下一个方向就变绿,并且返回这个变绿的方向以便操作。

5,交通灯管理器类,整个系统中只有一个交通灯管理器,这个类要设计为单例。交通灯管理器启动一个计划线程,每隔10秒将一个灯变红,并将下一个灯变绿。

6,main类,测试类,for循环出12条路线。创建一个交通灯管理器,启动其start方法。

类图设计

Road

属性,name;//表示方向,可以使用Lamp的枚举,vehicles;//车辆的集合

方法,在构造方法中,启动一个线程,每个一段随机时间就向车辆集合中增加一辆车;启动一个定时器,每个1秒,就检查该方向的灯是否为绿,绿就打印车辆集合中的第一辆车通过的信息并remove它。

Lamp

属性,12个方向,定义好其对面方向,灯绿否和下个方向;等的状态,isGreen;相反方向的灯,oppositeLampName;下一个灯,nextLampName;由于要在构造方法中定义一个方向的状态,反方向灯和下一个灯,但是枚举中无法在枚举定义之前引用这个枚举,所以使用字符串表示反方向灯和下一个灯。

方法,toGreen();toRed();,变灯,这两个方法中要让向反方向的灯也随之变化。toRed()方法中还要将下个灯变绿。

LampController

整个系统只有一个管理器,所以这个类设计为单例。在构造方法中需要将第一个灯设置为绿。

方法,start();这个方法中创建一个定时器,每隔10秒将当前灯变红,将下个灯变绿。

MainClass

for循环12条线路,创建一个LampController对象,并调用start()方法。

java实现

 

/**
 * 路线类
 * @author Administrator
 *
 */
public class Road {

	private String name;//路线的名字
	private List<String> vehicles = new ArrayList<String>();//车辆名字
	/*
	 * 构造方法中获取路线名字和创建线程判断路灯给车辆放行,创建线程随机增加车辆
	 */
	public Road(String name){
		this.name = name;
		//创建线程判断路灯,是否放行车辆,也可以同时定时器线程实现
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				while(true){
					//获取本线路的路灯
					boolean isGreen = Lamp.valueOf(Road.this.name).isGreen();
					//判断路灯
					if(isGreen){
						if(vehicles.size() > 0){
							//车辆通过路口的时间为一秒
							try {
								Thread.sleep(1000);
								System.out.println(Road.this.name + ":" + vehicles.remove(0) + "通过路口");
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
				}
			}
		});
		//创建线程随机增加车辆
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			public void run() {
				//一共增加100两车上路
				for(int i = 0; i < 1000; i++){
					//利用随机数每个1-5秒出现一辆车上路
					int interval = new Random().nextInt(4) + 1;
					try {
						Thread.sleep(interval * 1000);
						//将车辆放入队列
						vehicles.add("车辆_" + i);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		});
	}
}

 

/**
 * 交通灯枚举
 * @author Administrator
 * S2N,S2W,E2W,E2S,
	N2S,N2E,W2E,W3N,
	S2E,N2W,W2S,E2N;
 */
public enum Lamp {
	//十二个路线
	S2N("N2S", false, "S2W"),S2W("N2E", false, "E2W"),E2W("W2E", false,"E2S"),E2S("W2N", false, "S2N"),
	N2S(null, false, null),N2E(null, false, null),W2E(null, false, null),W2N(null, false, null),
	S2E(null, true, null),N2W(null, true, null),W2S(null, true, null),E2N(null, true, null);
	private boolean isGreen = false;//是否为绿
	private String nextLamp;//下一个变色的灯
	private String oppositeLamp;//对面的灯
	
	/*
	 * 构造方法提供对面灯,颜色,下个灯这个三个属性
	 * 创建定时器,每隔10秒变灯
	 */
	private Lamp(String oppositeLamp, boolean isGreen, String nextLamp){
		this.nextLamp = nextLamp;
		this.oppositeLamp = oppositeLamp;
		this.isGreen = isGreen;
	}
	/**
	 * 获取灯的颜色
	 */
	public boolean isGreen(){
		return this.isGreen;
	}
	/**
	 * 变绿
	 */
	public void toGreen(){
		//本灯变绿
		this.isGreen = true;
		//对面灯变绿
		Lamp.valueOf(this.oppositeLamp).isGreen = true;
	}
	/**
	 * 变红
	 */
	public Lamp toRed(){
		//本灯变红
		this.isGreen = false;
		//对面的灯也变红
		Lamp.valueOf(this.oppositeLamp).isGreen = false;
		//获取下个灯
		Lamp next = Lamp.valueOf(this.nextLamp);
		//下个灯绿
		if(next != null){
			next.toGreen();
		}
		//返回下个灯
		return next;
	}
}

 

/**
 * 交通灯管理类
 * @author Administrator
 *
 */
public class LampManager {
	//定义一个当前灯的属性
	Lamp currentLamp = Lamp.S2N;
	//全局只有一个交通灯,所以这个类设计为单例
	private LampManager(){}
	//创建一个懒汉单例
	private static LampManager lampManager = new LampManager();
	//获取这个单例
	public static LampManager getLazyInstance(){
		return lampManager;
	}
	//设计一个定时器,每隔10秒变灯
	public void start(){
		//起初,将当前灯变绿
		currentLamp.toGreen();
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					public void run() {
						currentLamp = currentLamp.toRed();
						System.out.println(currentLamp + "灯变绿了");
					}
				}, 
				0, 
				10, 
				TimeUnit.SECONDS
			);
	}
}

 

/**
 * 测试方法
 * @author Administrator
 *
 */
public class MainClass {
	public static void main(String[] args) {
		//for12条线路
		Lamp[] lamps = Lamp.values();
		for(Lamp lamp:lamps){
			String name = lamp.name();
			Road road = new Road(name);
			System.out.println(name + "开通了");
		}
		//创建一个交通灯管理器
		LampManager lampManager = LampManager.getLazyInstance();
		//开启对交通灯的管理
		lampManager.start();
	}
}

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值