项目名称:交通灯管理系统
项目内容要求:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
用面向对象的方法进行分析:根据题目要求涉及到的对象有:车、路、灯、灯的变换管理;
分析车:本题中没有涉及用到测本身的属性,所以不创建车得类。
分析路:根据谁拥有数据,方法就定义在谁身上。因为路上有没有车得问路,所以不用定义专门管理车得类,问路就可以了。所以在路上定义一个集合用于存储车。车走不走要灯,所以每条路要对应一盏灯,路调用灯的方法看看是否可以行车。有路当然要有路线,路线如下
代码如下:
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Random;
importjava.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
importjava.util.concurrent.TimeUnit;
publicclass Load {
List<String>list=new ArrayList();
String name;
Load(String name){
this.name=name;
ScheduledExecutorServicedai = Executors.newScheduledThreadPool(1); //定义了一个线程池
dai.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) {
// TODOAuto-generated catch block
e.printStackTrace();
}
list.add(Load.this.name+"..........."+i); //随机的向路上来车
}
}
});
ScheduledExecutorServiceli = Executors.newScheduledThreadPool(1);
li.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(list.size()>0){ //判断路上是否有车
if(Lamp.valueOf(Load.this.name).flag)//判断是否是绿灯
System.out.println(list.remove(0)+"..........zou le");//移走第一辆车
}
}
}
, 1
, 1
,
TimeUnit.SECONDS
);
}
}
分析灯:一共有12盏灯,但是右拐弯的灯视为常绿,所以不用考虑,还剩下八盏灯,因为两两对应,所以只需考虑四盏灯即可,因为12盏灯是固定的,所以要定义成枚举类。因为灯是绿是红只有灯自己清楚,下一盏灯是哪个变绿也只有等自己知道,所以要将这些方法定义到灯上。
代码如下:
publicenum Lamp {
e2w("e2s","w2e",false),e2s("n2s","w2n",false),n2s("n2e","s2n",false),n2e("e2w","s2w",false),
w2e(null,null,false),w2n(null,null,false),s2n(null,null,false),s2w(null,null,false),
e2n(null,null,true),n2w(null,null,true),w2s(null,null,true),s2e(null,null,true);
Lamp(Stringnext,String opposite,booleanflag){
this.flag=flag;
this.next=next;
this.opposite=opposite;
}
boolean flag;
String next;
String opposite;
public boolean light(){ //返回灯的情况
return flag;
}
public void Light(){ //让自己以及对面的灯变亮
flag=true;
if(opposite!=null){
Lamp.valueOf(opposite).flag=flag;
}
}
public Lamp unlight(){ //让自己以及对面的灯变黑
flag=false;
if(opposite!=null){
Lamp.valueOf(opposite).flag=flag;
}
Lamp Org=null;
if(next!=null){
Org=Lamp.valueOf(next);//让下一个灯变亮
Org.Light();
}
return Org;
}
}
分析灯的控制系统:就是控制等的变换时间
代码如下:
importjava.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
importjava.util.concurrent.TimeUnit;
publicclass Loadlight {
Loadlight() {
final Lamp lamp =Lamp.e2n;
lamp.Light();
// TODOAuto-generated constructor stub
ScheduledExecutorServicejuan = Executors.newScheduledThreadPool(1);
juan.scheduleAtFixedRate(
new Runnable(){
Lamp lm=null;
@Override
public void run() {
// TODOAuto-generated method stub
lm=lamp.unlight();
}
},
10,
10,
TimeUnit.SECONDS
);
}
}
测试类:
代码如下:
publicclass mainClass {
/**
* @param args
*/
public static voidmain(String[] args) {
// TODOAuto-generated method stub
String[] load={
"e2w","e2s","n2s","n2e",
"w2e","w2n","s2n","s2w",
"e2n","n2w","w2s","s2e"};
for(int i=0;i<load.length;i++){
new Load(load[i]); //定义了12条路
}
new Loadlight();
}
}
运行结果:
不足之处:灯的控制系统类,它是用来控制交通灯的,当他对外暴露时,会引起系统的安全隐患,如果有非法人员(或操作错误)可能会引发交通事故,所以这个类应当进行隐藏。隐藏方法有:将其抽象化,将其变为接口,封装成灯的内部类。我在这里将其抽象化。
灯的控制系统代码如下:
publicabstract class Loadlight {
Loadlight() {
final Lamp lamp =Lamp.e2n;
lamp.Light();
// TODOAuto-generated constructor stub
ScheduledExecutorServicejuan = Executors.newScheduledThreadPool(1);
juan.scheduleAtFixedRate(
new Runnable(){
Lamp lm=null;
@Override
public void run() {
lm=lamp.unlight();
}
},
10,
10,
TimeUnit.SECONDS
);
}
}
测试类代码如下:
publicclass mainClass {
/**
* @param args
*/
public static voidmain(String[] args) {
String[] load={
"e2w","e2s","n2s","n2e",
"w2e","w2n","s2n","s2w",
"e2n","n2w","w2s","s2e"};
for(int i=0;i<load.length;i++){
new Load(load[i]); //定义了12条路
}
new Loadlight(){};
}
}
运行结果:
总结:通过这个系统是我懂得了“谁拥有数据就把方法定义在谁身上”,路拥有数据就把方法定义在路身上。车得一切行动,都要问路,灯是固定的,所以想到了枚举类,用枚举来定义。
在考虑问题时,应从不同的角度去观察,多元化的分析问题。能简化问题,从而得到问题的本质。
在程序中应用到线程池这一类,它加强了线程类,使代码更加的优化。在以后的学习当中我们要时时的关注着JDK动态,新的知识有利于编码。新的知识也是无数人知识的沉淀和汇总。
在代码编写过程中,也暴露了一些我的问题。如编写马虎、不能系统的分析系统等。这些都是我必须加强的。