黑马程序员之交通灯管理系统

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

由于路只有12个方向,所以需要12个方向的灯来分别控制每一条路:
南北灯(直行),南西灯(左转),南东灯(右转)
北南灯(直行),北东灯(左转),北西灯(右转)
东西灯(直行), 东南灯(左转),东北灯(右转)
西东灯(直行), 西北灯(左转), 西南灯(右转)

1,Road类
   Road类有两个成员变量,一个是路名name,一个是车辆集合vehicles
   在Road类的构造方法中,利用线程实现随机增加车辆的方法,并且启动定时器,随时判断能够通过路口。
2,Lamp类
   利用枚举实现Lamp类,因为路只有12个方向,所以Lamp类的对象只有12个,分别对应12条路。
   Lamp类的构造方法,要传入3个参数,分别为对面的灯opposite,下一个要变绿的灯next,还有一个用于判断当前灯红绿的变量lighted。
   Lamp类要有判断当前灯是绿还是红的方法isLighted
   Lamp类要有设置当前和对面灯为绿灯的方法light
   Lamp类要有设置当前和对象灯为红灯的方法lightOut,并且设为红灯后,要把下一个要变绿的灯next变为绿灯,并且把下一个变绿灯的对面的灯也设置为绿灯。
3,LampController类
   LampController类是控制系统,控制多长时间变绿或者变红,所以LampController类要有一个定时器进行定时,固定时间使得不同方向的灯交替变绿

学习心得:通过这个小系统,应该学会面向对象的设计方法,即谁拥有数据,谁就对外提供操作这些数据的方法。

典型案例
    ①人在黑板上画圆,可以抽象为几个对象:人,黑板,圆?那么画圆的动作是哪个对象的方法?画圆需要圆心和半径,那么圆心和半径是谁的数据?是圆,所以画圆的方法应该由圆来提供。
    ②列车司机紧急刹车:有两个对象列车和司机,刹车的方法是谁提供?很明显是列车,因为列车拥有速度、发动机等数据。
    ③售票员正在统计售货小票的金额:统计金额的方法由售货小票提供。人只是调用了售货小票的方法。
    ④人把门关上了:关门的方法由门提供。人只是调用了门的关门方法。
    ⑤路上有很多汽车,路上还要增加新的汽车,还要随时减少汽车:减少汽车的方法由谁提供?由路提供。
    ⑥两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子:对象:石头,石刀,树,木材,椅子。石头可以磨成石刀,那么是石头要提供方法把自己变成石刀?错,把自己变成刀,自己都没了。石头并没有石刀的属性,所以不能提供变成石刀的方法。所以定义一个石刀加工厂,KnifeFactory提供生成石刀的方法。石刀又有砍树的方法,返回木材。同理,椅子加工厂chairFactory提供方法,把木材变成椅子。
    ⑦球从一根绳子的一端移到了另一端:两个对象:小球、绳子。绳子的本质是为球的移动提供了方向,提供球要滚动到哪一点,所以绳子要提供一个方法nextPoint,返回小球要移动的下一个点。小球的构造方法中,把开始的点和绳子对象传给小球,小球还有移动的方法,调用绳子的方法nextPoint。

 交通灯的源代码

Lamp类:

package traffic;

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 boolean lighted;//存储每个Lamp对象中的亮黑状态
	private String opposite;//对面的灯
	private String next;//下一个要变绿的灯
	
//	private Lamp(){}
	
	private Lamp(String opposite,String next,boolean lighted){
		System.out.println("对面的灯:"+opposite+" 下一个绿灯:"+next+" 亮灭:"+lighted);
		this.opposite = opposite;
		this.lighted = lighted;
		this.next = next;
	}
	
	//现在的灯是不是亮的
	public boolean isLighted(){
		System.out.println(toString()+"是否是绿灯:"+lighted);
		return lighted;
	}
	//亮灯,绿灯
	public void light(){
		this.lighted=true;
		System.out.println(toString() + " lamp is green.下面有6个方向的车通过");
		//不进行判断会死循环
		if(opposite != null){
			//获取对面的灯的对象,使其也变亮
			Lamp.valueOf(opposite).light();
		}
	}
	//把当前灯变为红灯,并返回要变绿的灯
	public Lamp lightOut(){
		this.lighted =false;
		if(opposite!=null){
			Lamp.valueOf(opposite).lightOut();
		}
		Lamp nextlamp = null;
		if(next!=null){
			nextlamp=Lamp.valueOf(next);
			nextlamp.light();
			System.out.println("绿灯从"+ name()+"---->切换为"+ next);
		}
		return nextlamp;
	}
}


灯控制器:LampController

package 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.light();
		//每隔10秒当前灯变黑
		ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run() {
						System.out.println(currentLamp+"即将变为红灯");
						currentLamp = currentLamp.lightOut();
					}
					
				}, 
				10, 
				10, 
				TimeUnit.SECONDS);
	}

}

路:Road

package 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 {
	//每个Road对象都有一个name成员变量来代表方向,有一个vehicles成员变量来代表方向上的车辆集合
	private List<String> vehicles = new ArrayList<String>();	
	private String name = null;
	
	public Road(String name){
		this.name = name;
		//jdk1.5的线程库Executors
		ExecutorService pool = Executors.newSingleThreadExecutor();
		//在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车
		//Runalbe是接口不能直接new,所以这里new了个接口实现类的对象
		pool.execute(new Runnable(){
			public void run() {
				for(int i= 1;i<1000;i++){
					try {
						//产生1-10之间的随机整数
						Thread.sleep((new Random().nextInt(10)+1)*1000);
						System.out.println(Road.this.name+"线程到底是个什么东西");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					//内部类想要访问外部类的局部变量,外部类的局部变量要加上final修饰
					//这里也可以访问外部类的成员变量来实现
					//访问外部类的成员变量本来可以直接写外部类的成员变量名,
					//但是如果这个变量与自己类里的变量名冲突了,要加上类名.this.变量名
					vehicles.add(Road.this.name + "_" + i);
					System.out.println("牌照为"+Road.this.name + "_" + i + "的车来了");
				}
				
			}
			
		});
		
		//在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则将集合中的第一辆车移除掉
		ScheduledExecutorService  timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable(){

					public void run() {
						if(vehicles.size() > 0){
							boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
							//布尔型的变量直接用,不用和true去比较了lighted==true
							if(lighted){
								System.out.println(vehicles.remove(0)+"开走了!");
							}
						}
					}
					
				}, 
				1, 
				1, 
				TimeUnit.SECONDS);

	}
}


主程序:

package traffic;

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(); 
		
	}

}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值