您的位置:首页 > 职场人生

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

2013-11-25 16:03 225 查看
------------------
android培训、java培训、期待与您交流! ---------------------
一、需求分析:

每条路都有 直走,左转弯,右转弯三个路线,所以东西南北四条路总共有12条路线。

由于,相对的两个路口,红绿灯应该是一致的,并且右转弯不需要红路灯控制,相当于常绿。

因此,可以将问题简化成不想对的两条路、四个路线的问题。比如,南和东的直走和左转弯的路线问题。

二、面向对象的分析与设计

1、对象:红绿灯,红绿灯的控制系统,汽车,路线。

2、思路分析:

各个路线上的汽车,首先看该路线上的红绿灯状况,如果为绿,再看自己前面是不是有其他车辆,如果没有,那么这辆车就可以通过路口了。那么,路线中应该存储车辆集合,并且有对车辆的增加和减少的功能。

另外,我们只是捕获车辆过路口的过程,并不研究车辆移动过程,所以车辆不需要单独设计成一个对象,用一个字符表示就行了。

3、红绿灯Lamp:

可以用枚举来定义十二个灯。灯有绿灯green()、红灯red()方法。一个灯,如果它是绿灯,那么它相对的灯也应该变绿。如果它变红了,那么它对面的灯也要变红,并且它的下一个灯要变绿。注意右转弯的灯始终是绿的。

4、红绿灯的控制系统LampControl:

要定义一个定时器,每隔十秒钟变换一下灯的红绿。首先初始化一个路线的灯为绿灯,然后定时调用当前灯的红灯red方法,并且返回下一个灯为当前灯,这样才能往复循环。所以Lamp类中的red方法要返回当前等的下一个灯。

5、路线Road:

每条的路线都有一个初始化的名称,这个名称和各个路线的红绿的最好对应。每条路要随机生成若干辆车,比如1000辆。也要定义一个定时器,用于每隔一秒钟观察一下自己线路上的红绿的灯,如果是绿灯就通过车辆。

6、测试类TrafficTest创建十二条路线,并且初始化红绿灯的控制系统。

三、代码实现:

1、红绿灯Lamp:

public enum Lamp {
//只有这四个是含有逻辑的灯,控制了这四个灯,对应的就控制了。
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
//下面四个灯是上面四个灯的对面opposite,受上面灯的控制,这些灯的opposite为null,以防死循环
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;
//如果lighted为true则为绿灯
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 green(){
this.lighted = true;
System.out.println(name()+"is changed Green,下面六个路线的车辆可以行走");
if(opposite != null){
Lamp.valueOf(opposite).green();
}
}
//让灯变红灯,如果这个灯变成红灯,那么它对面的灯也变成红灯,且它的下一个灯next变成绿灯
public Lamp red(){
this.lighted = false;
//先让自己变红
if(opposite != null){
Lamp.valueOf(opposite).red();
}
//紧接着让下一个变绿,

Lamp nextLamp = null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println(name()+"的下一个路口切换成绿灯了");
nextLamp.green();

}
return nextLamp;
}
}
2、红绿灯的控制系统LampControl:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 这是一个红绿灯控制器,实现每隔十秒钟,切换成下一个路口的灯变绿
* */
public class LampController {
//声明一个当前灯currentLamp
private Lamp currentLamp;
public LampController(){
currentLamp = Lamp.S2N;
//刚开始就让当前的灯变绿
currentLamp.green();
//然后定义一个定时器,每隔十秒钟当前灯变红,并且下一个灯变绿
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("红绿灯切换");
//每隔10s调用red方法让当前的灯变红,当前的下一个灯变绿,并且要返回当前灯的下一个,如果不返回,当前灯将永远是S2N
currentLamp = currentLamp.red();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
3、路线Road:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
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> vehicles = new ArrayList<String>();//使用List是面向接口编程
private String name;
public Road(String name){
this.name = name;
//模拟车辆不断随机上路的过程
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
@Override
public void run() {
for(int i = 0; i < 1000;i++){
try {
//随机睡1-10s然后增加车辆,相当于随机生成车辆上路
Thread.sleep((new Random().nextInt(10)+1)*1000);//随机生成1-10,还可以使用Math.random()*10+1查一下
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vehicles.add(Road.this.name+"这条路上的第"+(i+1)+"辆车!");
}
}});
//每隔一秒钟 检查一下该路线上的红绿灯,绿灯就过
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if(vehicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vehicles.remove(0) + " is traversing !");
}
}

}
},
1,
1,
TimeUnit.SECONDS);
}
}
4、测试类TrafficTest:
public class TrafficTest {

public static void main(String[] args) {
// TODO Auto-generated method stub
/*产生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();
}

}


四、面向对象设计的重要经验:

谁拥有数据,谁就对外提供操作这些数据的方法。

1、几个例子
*人在黑板上画圆:对象有人、黑板、圆。画圆的方法是圆拥有的,用到它自身拥有的圆心和半径。
*列车司机紧急刹车:对象有列车、司机。刹车的方法是列车的。
*售货员统计收货小票的金额:对象有售货员、小票。统计金额的方法是小票的方法。
*你把门关上:对象有人、门。关门的方法是门的方法,门拥有转动轴。
2、两个面向对象的面试题,用面向对象的方式设计如下情景。
*球从一根绳子的一端移动到了另一端。
对象:球、绳子。球有一个移动的方法,按照某个坐标移动。
*两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子。
对象:石头,石刀,树,木材,椅子。石刀工厂,木材厂,椅子厂。
石刀工厂:将两块石头返回一个石刀。
木材厂:将树返回木材。
椅子厂:将木材返回椅子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: