------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------
交通灯项目需求:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
交通灯项目需求分析思路:
项目为模拟现实生活中的交通信号灯,为方便业务逻辑分析我们先来画图分析。
项目分为三大主体:路,交通灯,车。
如上图所示,根据需求我们得知一共有12条路线。南---->北,北.---->南,南---->西,北---->东,东---->西,西---->东,东---->南,西---->北,南---->东,北---->西,东---->北,西---->南。
每条路有自己的车,车为路的数据,所以根据面向对象设计模式 ,设计Road类,封装road类。
Road类应该具有的方法和属性。
name:路的方向。
vechicles:存储车辆的集合。
public Road(String name):
构造方法,在创建路对象的时候,因该给路一个名字,然后用这个名字的信号灯来控制此的可行与否。
应该不断有车上路并排队过信号灯,所以创建Road对象时,应该加一个线程,每过若干时间为这条路上增加一辆车。
定时器:路应该每过1秒来判断一下此路是否可通行(是否为绿灯),然后让车队里的每一辆车从第一辆开始过路口。
package com.isoftstone.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 {
private List<String> vechicles = new ArrayList<String>();//车辆集合
private String name=null;//名字方向。
public Road(){
//无参构造方法
}
public Road(String name){
this.name=name;//路的方向
ExecutorService pool= Executors.newSingleThreadExecutor();
pool.execute(
new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//随机(1-10)秒后给本路添加一辆汽车
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);//随机(1-10)秒后给本路添加一辆汽车
}
}
}
);
ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);
timer.scheduleWithFixedDelay(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);
}
}
如上图所示,根据需求我们得知一共有12条路线。南---->北(S2N),北.---->南(N2S),南---->西(S2W),北---->东(N2E),东---->西(E2W),西---->东(W2E),东---->南(E2S),西---->北(W2N),南---->东(S2E),北---->西(N2W),东---->北(E2N),西---->南(W2S)。
12条路线因该由12个信号灯来指挥当前哪条线路可行驶。
信号灯应该具备的属性:
相对的灯:opposite;//相对的灯的可行状态始终和this一样。例:南往北为绿灯,北往南也为绿灯。
接下来变绿的灯;next;
当前灯可行状态:lighted;
方法:
构造方法:Lamp(String opposite,String next ,boolean lighted);//为灯设置属性。
得到灯的可行状态:isLighted();
设置等的可行状态为true:light();
变灯(把当前所有绿灯关闭,开启接下来路线绿灯):blackOut();
需求“:
右转车辆不受信号灯控制
车辆行驶顺序,假如南北先为绿灯:
1. 南---->北 北.---->南
10秒后,南北绿灯变为红灯,南---->北 北.---->南不可行。换为左拐:
2. 南---->西 北.---->东
10秒后,南西左拐绿灯变为红灯,南---->西 北.---->东不可行。换为东西直行:
3. 东---->西 西---->东
10秒后,东西绿灯变为红灯东---->西 西---->东不可行。换为东西左拐:
4.东---->南 西---->北
10秒后。。。。第四步跳回第一步,依次循环变灯。
了解需求后,我们来写这个类,因为这12个灯为固定不变,所以这里我用枚举。
package com.isoftstone.interview.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 String opposite;//当前绿灯的方向
private String next;//下一个绿灯的方向
private boolean lighted;//
private Lamp(){};
private Lamp(String opposite,String next ,boolean lighted){
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
//得到当前灯是否可行。
public boolean isLighted(){
return lighted;
}
//把当前灯和当前灯的对面灯设置为绿灯可行。
public void light(){
this.lighted=true;
if (opposite!=null){
Lamp.valueOf(opposite).light();
}
}
//把当前灯和当前灯对面的灯设置为红灯,并把接下来应该转为绿灯的灯和他的对面灯转为绿灯。
public Lamp blackOut(){
this.lighted=false;
if (opposite!=null){
Lamp.valueOf(opposite).blackOut();
}
//Lamp nextLamp=Lamp.valueOf(next);
Lamp nextLamp = null;
if (next!=null){
//nextLamp=Lamp.valueOf(next);
Lamp.valueOf(next).light();
System.out.println("绿灯从"+name()+"------------>切换为"+next);
}
return nextLamp;
}
}
写到这里灯的设计和代码都写出来,这里还差一个控制灯的一个控制器,让灯每过10秒按照需求变化。
package com.isoftstone.interview.traffic;最后一步:创建一个灯控制器和12个方向的路,路会自动增加车辆,灯会每个一段时间自动变换。绿灯的路会让车辆一辆一辆通过。
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();
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
System.out.println(currentLamp.name());
currentLamp=currentLamp.blackOut();
if(currentLamp==null){
System.out.println("null");
}
}
}
,
10,
10,
TimeUnit.SECONDS
);
}
}
package com.isoftstone.interview.traffic;
class MainClass {
/**
* @param args
*/
public static void main(String[] args) {
Lamp nextLamp=Lamp.valueOf("dfdfdf");
// TODO Auto-generated method stub
String [] directions=new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","E2W","W2S"
};
for(int i = 0 ;i<directions.length;i++){
new Road(directions[i]);
}
new LampController();
}
}
项目感言
交通灯在现实生活中是一个实实在在的项目,虽然我们现在写的这个小程序只是实现了一些个简单的逻辑,但是这个小项目他培养的是编程设计的思维,拿到一个项目首先得会分析需求,然后实现需求。写程序之前学好基础固然重要,但是也一定得会设计程序。一个好的程序员必须要有好的基础和好的思维。这个小项目如果写得出来,我相信我将来可以实现更复杂的逻辑。非常感谢张老师!
------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------