---------------------- Android培训、java培训、期待与您交流! ----------------------
一、分析交通路线。
以路口为准,每个方向来车看成一组,共东、西、南、北4组车辆。
每组车辆都有3种行驶路线:向左、向右、直行,即:十字路口共12种行驶路线(如上图)。
为统一编程模型,可以假设每条线路都有红路灯进行控制,右转弯的
4条路线的控制灯可以假设称为常绿灯。除去右转弯路线以外还有8条路线的灯,
它们两两成对,(南北方向两个直行、两个左转;东西方向两个直行、两个左转
)共分成4组。每组两个信号灯的状态是一致的。所以只考虑每组中一种路线即可。
二、面向对象的分析与设计。
面向对象设计把握一个重要经验:谁拥有数据,谁就对外提供操作这些数据的方法。
初步分析项目中可以抽象为类的事物有:路线、交通灯、交通灯控制系统、车。
详细分析后发现车的行驶受到交通灯的限制,还要看前方是否有车辆即访问路线对象
的数据。路中存储着车辆的集合,显然应该有增加减少车辆的方法。题目中不要求体现
车辆的移动过程,只是捕捉路上减少一辆车的过程。所以车不需要单独设计一个类,用
一个字符串表示就可以了。
1,路线类(Road):
(1:设计一个Road类来表示路线,每个Road对象代表一条路线,共12条路线,即要产生
12个Road实例对象。
(2:每个路线增加另一个集合用来存储线路上的车辆。
(3:每条路线每隔一秒都会检查本路线的灯是否为绿,是则将被路线保存车的集合的
第一辆车移除,即表示车辆穿过路口。
public class Road{
private List<String> vechicles = new ArrayList<String>();
private String name = null; //路线名称
public Road(String name){
this.name = name;
ExecutorService pool = Executors.newSingleThreadExecutor();//另起一个线程用于随机产生车辆。
pool.execute(newRunnable(){
for(int i=0; i<1000; i++){
try{
Thread.sleep((new Random().newInt(10)+1)*1000); //1~10秒随机驶来一辆车
}catch(InterryptedException e){
e.printStackTrace();
}
vechicles.add(Road.this.name + "-"+i);//内部类访问外部类成员变量
}
});
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //创建大小为1的线程池作为定时器。
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(vechicles.size()>0){
//调用Lamp枚举类valueOf方法得到当前路线上的灯。
boolean lighted = Lamp.valueOf(Road.this.name);
if(lighted){
System.out.println(vechicles.remove(0) + "is traversing !");//移除第一个元素表示开走第一辆车。
}
}
},//要执行的任务。
1,//一秒后开始执行。
1,//每隔一秒执行一次。
TimeUnit.SECONDS);//参数的时间单位。
}
}
2,交通灯类(Lamp):
(1:设计一个Lamp类表示一个交通灯,每个交通等都维护一个状态:亮(绿)后不亮(红),
交通灯要有变亮变黑的方法,并且返回自己的状态。因为该类中只有12个固定实例,所以想到了用枚举类来描述路线更优。
(2:12条路线则有12个交通灯,因为右转弯不受灯限制,为了保证程序采用统一处理方式,
则让右转灯常亮即可。
(3:除去右路线还有8条路线的灯,它们两两成对,(南北方向两个直行、两个左转;东西方向两个直行、两个左转
)共分成4组。每组两个信号灯的状态是一致的。
public enum Lamp{
S2N("N2S","S2W,false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
//被关联的灯不在有关联灯否则light()与blackOut()方法会进入死循环.
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);
pivate Lamp(String opposite,String next,boolean lighted){ //关联同组的灯,下一个灯,设置灯当前状态。
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
private boolean lighted;
private String opposite; //定义了String类型而没有直接定义Lamp类型,是因为对象没有被创建之前不能作为参数。
private String next;
public boolean isLighted(){ //判断灯是否是亮的
return lighted;
}
public void light(){ //点亮当前灯。
this.lighted = true;
if(opposite != null){ //如果有关联灯则一起点亮.
Lamp.valueOf(opposite).light();
}
}
public void blackOut(){ //关闭当前灯(亮红灯)。
this.lighted = false;
if(opposite != null){ //如果有关联灯则一起关掉。
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp = null;
if(next != null){
nextLamp = Lamp.valueOf(next);//获取下一个灯的实例对象
nextLamp.light();
}
return nextLamp; //当灭掉当前灯点亮当下一个灯后blackOut方法返回下一个灯,为控制器类使用。
}
}
3,交通灯控制器与主方法类:
public class LampController{
private Lamp currentLamp;
public LampController(){
//南开往北的路线上的灯先亮
currentLamp = Lamp.S2N;
currentLamp.light();
ScheduledExecutorService timer = new Executors.newScheduledThreadPool(1);//创建大小为1的线程池。
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
currentLamp = currentLamp.blackOut(); //每过十秒当前灯变红。
}
},
10,//10秒后开始执行。
10,//之后每10秒执行一次。
TimeUnit.SECONDS);//时间单位为秒。
}
}
public class mainClass{
public static void main(String[] args){
//用一个字符串数组存储将要建立的“Road对象的名称,便于建立对象。
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();//启动交通灯控制器。
}
}
---------------------- Android培训、java培训、期待与您交流! ----------------------