------- android培训、java培训、期待与您交流! ----------
交通灯项目:
A.分析项目需求:
1.一共有执行方向4条,左转方向4条,右转方向4条,信号灯状态有红和绿两种;
2.本题的项目需求中指出右转车辆不受信号灯控制,而左转车辆才受到车辆控制,
那么我们就可以假设右转方向的4条线路的信号灯是常绿的状态,只需考虑另外8条方向。
这8条方向又是两两成对的,那么就只用考虑4条路线的控制灯的切换顺序即可,问题就简化很多了。
3.信号灯控制逻辑与现实情况相同,红灯停,绿灯行!直行方向交替,同方向先直行,后左转。
B.面向对象分析:
牢记一个重要的面向对象设计经验:谁拥有数据,谁就对外提供操作这些数据的方法。
名词提炼法:本项目中共有汽车,路线,红绿灯,灯控制系统。
1.路线。可以将路看成是存储着车辆的集合,它里面有增加和减少车辆的方法;
2.车。项目只需要捕捉出车辆穿过路口的过程,所以车可以不必设计成一个对象,我们只需要用字符串表示就可以了;
3.红绿灯。可以设计一个Lamp类,该类有两种状态,并变红和变绿的方法,另外还应该有一个变量来记录相应方向的灯的状态,
因为每组灯之间存在着对应关系;考虑到Lamp类只有12个对象,所以可以设计成枚举类。
4.灯控制系统。设计一个LampController类来控制各个方向的灯,并使这些灯每隔固定的时间改变状态。
C.思路与步骤:
1.Road类。这个类有个属性name代表是哪个方向,有一个集合用来存储车辆并对车辆增删操作,
另外还有两个方法,分别用来模拟汽车不断的上路,以及检查该路线是的灯是否是绿色的,并根据灯的状态来删减车辆。
因为车辆是随机上路的,所有可以用Thread类中sleep()方法接受一个随机时间参数来模拟,而检查该路线的灯的状态是定时来运行的,
所有可以使用定时器来模拟。这个线程和定时器都在Road的构造方法中启动;
public class Road {
private List<String> vechiles = new ArrayList<String>();//定义一个集合用于存储不断上路的汽车
private String name;
public Road(String name){//每条路都有一个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) {
e.printStackTrace();
}
vechiles.add(Road.this.name+"_"+i);//模拟增加一辆车的过程
}
}
});
//Road类还有一个定时检查对应的灯是否为绿的方法,如果是绿灯就减少一辆车
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
//先判断这条路上有没有车
if(vechiles.size()>0){
//如果这条路上有车,再判断当前的等是否是绿色的
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechiles.remove(0)+"is traversing");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
2.Lamp类。设计成枚举。项目中共有12条路线,共有12个Lamp实例,每条路线上的灯的初始状态是不一样的。
可以通过构造方法进行赋值;另外类中应该有变亮和变黑两种方法,
注意,变亮时,应该把自己变亮,并把对应方向的灯也变亮,
变黑时,把对应方向的灯也变黑,并把下一个方向的灯也亮。并且该方法返回下一个要变绿的灯!
所以它还必须有两个变量来记录相反方向以及下一个方向的灯。
//当当前灯变绿时,它对应方向的灯也要变绿
public void light(){
this.lighted = true;
if(opposite!=null){
Lamp.valueOf(opposite).light();//valueOf()方法返回带指定名称的指定枚举类型的枚举常量。
}
System.out.println(name()+" lamp is green,下面总共应该有6个方向能看到汽车穿过");
}
//灯变红的方法,此时对应方向的灯也要变红,并且下一个灯要变绿,该方法返回下一个要变绿的灯
public Lamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp = null;
if(next != null){
//Lamp.valueOf(next).light();
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从"+name()+"---->切换为"+next);
nextLamp.light();//让下一个灯变亮
}
return nextLamp;//该方法返回下一个变亮的灯
}
3.LampController类。这个类用来控制以上12个灯,它在项目中只有一个对象,可以设计成单例。
定义一个当前灯变量,在构造方法中将当前灯变绿,然后用定时器,每隔固定时间将当前灯变红,下一个灯变绿;
注意:当前灯变红时,会自动的将对应方向的灯变红,并将下一个灯变绿,并且该变红的方法返回的是下一个变绿的灯,
所以可以用当前灯去记录该返回的灯,currentLamp = currentLamp.blackOut()就可以让currentLamp每隔10秒都可以调用blackOut()方法
从而控制其他灯。
4.MainClas类。使用for循环创建12条路,创建LampController类对象。
总结:本题的关键在于找到共有那几条路需要分析、车与路,路与灯,灯与控制系统之间的关系。
1.做这样的题目,应该先仔细分析项目需求,总共有多少路线、灯的状态、灯与车,车与路,路与灯之间是什么关系等等;
2.然后将需要定义的对象,描述成为一个类,类中定义该类的属性和行为。务必要分清楚哪些行为是哪个对象的,否则无从动手。
3.按照业务逻辑在测试类中调用各个类的方法,组织起来并反复测试。
总之,思路是最重要的,代码只是思想的一种体现而已,更重要的是分析业务逻辑,明确各个对象的属性和行为有哪些以及对象之间的关系。