------- android培训、java培训、期待与您交流! ----------
交通灯管理系统系统需求
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1.异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
2.信号灯忽略黄灯,只考虑红灯和绿灯。
3 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
6 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
系统分析
1.名词提炼法-------要求中涉及的名词:车辆,路线,信号灯;三者之间的关系,每条线路上都有不同信号灯和车辆。
2.设计模型:
十字路口共有12条路线,其中四条右转线路一直处于通行状态,其余8条线路,可分为方向相对的四组,每一组路线上的红绿灯状态一致,每组选取一条线路组成四条切换灯状态的线路。
线路模型:有自己的名字,车辆池,已建立就异步产生车辆和移动车辆,并根据其上的交通灯判断是否移除车辆。
交通灯模型:使用枚举,它记录对面的灯,以实现每组灯状态一致;记录下一个灯,以实现切换状态
交通灯控制系统模型:记录当前亮着的主控制灯,并定时切换。
3. 路线示意图
代码实现:
1.Road类
package cn.itcast.traffic;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
public class Road {
List<String> vechicles = new ArrayList<String>();//交通工具集合
private String name;
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) {
e.printStackTrace();
}
vechicles.add(Road.this.name + "_" + i);//将生成的车辆存放入交通工具集合中
}
}
});
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//如果是绿灯每秒模拟一次车辆过路口
timer.scheduleAtFixedRate(
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);
}
}
2.Lamp类
package cn.itcast.traffic;
public enum Lamp {
//为交通灯枚举类添加元素,即12个交通灯对象,
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 boolean lighted;//由于不需要考虑黄灯,所以用boolean类型,true代表绿灯,false代表红灯
private String opposite;
private String next;
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
private Lamp(){}
public boolean isLighted(){
return lighted;
}
public void light(){//将当前灯及对面灯变亮的方法
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name() + "灯变绿了" + "下面总共应该有6个方向能看到汽车穿过!");
}
public Lamp blackOut(){//将当前等及对面灯变红灯的方法,并将下一组等变绿灯,并返回下一组灯
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp = null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从"+name()+"--------->切换为"+next);
Lamp.valueOf(opposite).light();
System.out.println(name() + "灯变绿了" + "下面总共应该有6个方向能看到汽车穿过!");
}
return nextLamp;
}
}
3.LampController类(交通灯控制器)
package cn.itcast.traffic;
import java.util.concurrent.*;
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(){
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);//每隔10秒执行一次换灯
}
}
4.MainClass类(总成测试类)
package cn.itcast.traffic;
public class MainClass {
public static void main(String[] args){
String[] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
for(String direction : directions){//循环生成12条路线,并给定路线上指定的交通灯.
new Road(direction);
}
new LampController();//启动交通灯控制系统
}
}
1.要树立良好的面向对象编程思想,记住一个重要原则,谁拥有数据,谁就对外提供操作这些数据的方法.
2.判定一个动作或一个方法属于哪一个类的时候,要看谁对这个方法的实现方式最清楚,
例如:人关门,关门这个方法是门的,而人只是调用了门的关门方法,传递了一个力,不是人在关门,而是门在关门.
3.在思考一个问题或需求的时候,最有效的解决方式是先画图,把各种对象,元素,方法都画出来,先思考好相互之间的所属关系及联系,
只要将设计思路确定以后,敲代码就是在实现设计思路了.敲程序前先画图!!!