您的位置:首页 > 其它

模拟交通灯管理系统

2011-02-27 14:35 363 查看
需求:模拟实现十字路口的交通灯,

1、信号灯忽略黄灯,只考虑红灯和绿灯;

2、直线、左转车辆受信号灯控制,右转车辆不受信号灯控制

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

十字路口的模拟图:



根据需求我们需要抽象的类有:信号灯、信号灯控制器、路。

从十字路口的模拟图,可以看出南和北的路线相对应、东和西的路线相对应,这样我们只要考虑两个方向上的信号灯就可以了。假设我们只考虑由南向北和由东向西方向上的信号灯。

1、先设计信号灯:首先考虑灯的属性,灯亮与否;灯当前在那个方向上;当前灯灭了后下一个灯该在哪个方向上;灯还需要用来控制当前灯的变化方法。

假如我们用普通类来设计这个灯,可能会设计成这样:

public class Lamp {
private boolean lighted;
private Lamp opposite;
private Lamp next;

public Lamp(Lamp opposite,Lamp next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
/**
* 当前灯的状态
* @return
*/
public boolean isLighted(){
return lighted;
}

public void light(){
lighted = true;
if(opposite != null){
opposite.light();
}
}

public Lamp back(){
lighted = false;
if(opposite != null){
opposite.back();
}

Lamp nextLamp = null;
if(next != null){
next.light();
nextLamp = next;
}
return nextLamp;
}
}

若设计成这样,当我们在创建这个类的时候会发现这个类创建不出来,因为当创建A时需要先创建B和C,而创建B又需要先创建D等等,所有我们考虑用枚举来做。

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 lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}

其他合上面的方法一样

}

灯设计好了,现在设计灯的控制器

2、设计信号灯的控制器:控制器主要作用是控制每隔多久灯变化一次。考虑到控制器肯能被多个路口调用,且在整个系统中又是独立的,故将其设计成单例。

public class LampContraller {
private Lamp currLamp;
private static LampContraller instance = new LampContraller();
private LampContraller(){
Lamp opposite = new Lamp(null,null,false);
Lamp next = new Lamp(null,null,false);
currLamp = new Lamp(opposite,next,false);
currLamp.light();
}

public static LampContraller getInstance(){
return instance;
}
public void contrallCode(){
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currLamp = currLamp.back();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
接下来就剩下路的设计了

3、首先要考虑的是车是在路上的,所有需要有个存储车的空间,其次是这个路的名称;还有车辆到了当前路口和车辆离开当前路口的方法。代码如下:

public class Road {
private List<String> cars = new ArrayList<String>();
private String roadName = "";

public Road(String name){
this.roadName = name;
carOnRoad();
carMoveRoad();
}

/**
* 车到了路口
*/
private void carOnRoad(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cars.add("车辆"+Road.this.roadName + "_" + i);
System.out.println("车辆"+Road.this.roadName + "_" + i+"到了路上");
}
}
});
}
/**
* 车开走了
*/
private void carMoveRoad(){
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable(){
public void run(){
if(cars.size() > 0){
boolean lampStatus = false;
if(lampStatus){
System.out.println(cars.remove(0)+"离开了路上");
}
}
}
}, 1, 1, TimeUnit.SECONDS);
}
}

好了设计完成。这里需要注意的是不要被方向给绕进去了,考虑使用枚举。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: