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

交通灯管理系统项目需求:

模拟实现十字路口的交通灯系统逻辑,具体需求如下:

异步随机生成按照各个路线形式的车辆。

              由南向而来去往北向的车辆---直行车辆

              由西向而来去往南向的车辆---右转车辆

              由东向而来去往南向的车辆---左转车辆

              ......

信号灯忽略黄灯,只考虑红灯和绿灯。

应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

具体信号灯控制逻辑与现实生活中普通交通灯扩至逻辑相同,不考虑特殊状况下的控制逻辑。

       注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直线车辆而

       后放行左转车辆。

每辆车通过路口时间为1秒(提示:可通过线程sleep的方式模拟),随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

不要求实现GUI,值考虑系统逻辑实现,可通过log方式展现程序运行结果。

线路数量分析:

总共有12条线路,为了统一编程模型,可以假设每条路线上都有一个红绿灯对其进行控制,右转弯的4条线路的控制灯可以假设为常绿状态,另

外其它的8条线路是两两成对的,可以归为4组,所以,程序只需要考虑途中标注了数字号的控制灯切换顺序,这4条路线相反的路线的控制灯

随着4条线路切换,不必考虑其它。

线路对应分析(相对方向亮)

①南-->北

 

⑤北-->南

②南-->西

 

⑥北-->东

③东-->西

 

⑦西-->东

④东-->南

 

⑧西-->北

 

面向对象的分析与设计:

(***补充:面向对象设计把握一个重要的经验——谁拥有数据,谁就对外提供操作这些数据的方法)

 

详细设计:(工程名traffic)

一、类

1、Lamp枚举类,灯

1.1 每个枚举元素各表示一个方向的控制灯

S2N("N2S","S2W",false),

S2W("N2E","E2W",false),

E2W("W2E","E2S",false),

E2S("W2N","S2N",false),

1.2 下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!

N2S(null,null,false),

N2E(null,null,false),

W2E(null,null,false),

W2N(null,null,false),

1.3 由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯

S2E(null,null,true),

E2N(null,null,true),

N2W(null,null,true),

W2S(null,null,true);

 

2、控制系统LampController

2.1获取当前等的变量

2.2获取一定时器,时间到,当前等转为红灯,并且下一个方向的等转为绿灯

 

3、路Road

 

二.部分所需类以及方法整理:

1

ExecutorService pool = Executors.newScheduledThreadPool(1);

创建一个线程池,-------------线程池(线程数)

2

Road.this.name

//第一种解决方案:内部类访问外部类成员变量,在外部类名前加final

//返回外部类的成员变量,为了避免与自己内部类的名字打架,所以:Road.this.name

3

new Random().nextInt(10)

//返回0~9的随机数

4

ScheduledFuture<?>   schedule(Runnable command, long delay, TimeUnit unit)

//创建并执行在给定延迟后启用的一次性操作。

//(线程,推迟时间,推迟时间单位)

5

ScheduledFuture<?>  scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

//创建并执行开始时间,然后过了多少秒之后继续干,再过多少秒再干, 再过多少秒再干, 再过多少秒再干......

//(线程,过多少秒之后去做,然后过多少秒再去干,时间单位)

6

TimeUnit.SECENDS

//时间单位.事件类型

7

valueOf(Class<T> enumType, String name)

返回带指定名称的指定枚举类型的枚举常量。

 

 

代码实现:

-----------------Road.java----------------------

 1 package cn.itcast.interview.traffic;
 2 //马路
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.Random;
 6 import java.util.concurrent.ExecutorService;
 7 import java.util.concurrent.Executors;
 8 import java.util.concurrent.ScheduledExecutorService;
 9 import java.util.concurrent.TimeUnit;
10 
11 public class Road {
12     //车的集合
13     private List<String> vechicles = new ArrayList<String>();//为了面向接口编程,所以是List集合
14     
15     private String name=null;
16     //每条路线的名字
17     public Road(String name)//内部类访问外部类,想访问外部类的局部变量,外部类必须加final(final String name)
18     {
19         this.name = name;
20         //新建一个线程,用于添加汽车
21         //newScheduledThreadPool线程池(线程数)
22          ExecutorService  pool= Executors.newScheduledThreadPool(1);
23         
24          //创建一个线程,定隔多少秒进行休息
25          pool.execute(new Runnable()//执行池执行,new 了一个Runnable()实现对象
26         {
27             public void run()
28             {
29                 for(int i =1;i<1000;i++)//产生999辆车
30                 {
31                     try {
32                         Thread.sleep((new Random().nextInt(10)+1)*1000);//返回0~9的随机数,再加一,就可以是1~10秒
33                     } catch (InterruptedException e) {
34                         e.printStackTrace();
35                     }
36                     vechicles.add(Road.this.name+"_"+i);//返回外部类的成员变量,为了避免与自己内部类的名字打架,所以:Road.this.name
37                 }
38             }
39         });
40          
41          //定时器
42          ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
43          
44          //循环定时器
45          timer.scheduleAtFixedRate(new Runnable(){
46                  public void run()
47                  {//首先检查是否有车
48                      if(vechicles.size()>0)
49                      {
50                          /*定义变量,之后就是在这里修改的..修改去检查这个灯
51                          boolean lighted = true;
52                          检查自己的灯,name为自己路线的名字,然后Lamp.valueOf(Road.this.name)获取自己路线的名字,
53                          把自己的名字传过去,就获得了自己的灯*/
54                          boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
55                          
56                          if(lighted)
57                         //假如灯是绿的
58                          System.out.println(vechicles.remove(0)+"is traversing !");
59                      }
60                  }
61                   },
62                  1,//开始时间
63                  1,//循环时间
64                  TimeUnit.SECONDS);//时间单位
65     }
66 }
Road.java

-----------------Lamp.java----------------------

 1 package cn.itcast.interview.traffic;
 2 //
 3 
 4 public enum Lamp {
 5     //首先定义12个方向变量
 6     //这四个是进行控制的
 7     S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
 8     
 9     //这四个的变量是随着上面而变的
10     N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
11     
12     //下面的四个是长亮的
13     S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
14     
15     private Lamp(String opposite,String next,boolean lighted)////小提示:枚举的构造方法必须是私有的
16     {
17         this.opposite = opposite;
18         this.next = next;
19         this.lighted = lighted;
20     }
21     private Lamp()//不带参数的构造方法,为了让空值的家伙们不报错,因为有的没有对应的灯
22     {
23         
24     }
25     
26     
27     //灯是否是亮的变量
28     private boolean lighted;
29     //对应的灯
30     private String opposite;
31     //定义下一个灯
32     private String next;
33     
34     
35     //亮的为绿,灭的为红,首先默认的为亮的
36     public boolean isLighted()
37     {
38         return lighted;
39     }
40     
41     //变绿
42     public void light()
43     {
44         this.lighted = true;
45         //判断一下是否有对应的灯,有对应的灯,然后再变亮
46         if(opposite !=null)
47         {
48             Lamp.valueOf(opposite).light();//传递对应灯的字符串,然后valueOf(),
49             //valueOf()返回带指定名称的指定枚举类型的枚举常量。
50         }
51         
52         //测试用
53         System.out.println(name()+"lamp is green.下面共有6个方向的车穿过...");
54     }
55     //熄灯..变红
56     public Lamp blackOut()
57     {
58         this.lighted = false;
59         if(opposite !=null)
60         {
61             Lamp.valueOf(opposite).blackOut();//传递对应灯的字符串,然后valueOf(),
62             //valueOf()返回带指定名称的指定枚举类型的枚举常量。
63         }
64         
65         Lamp nextLamp = null;
66         
67         //如果有下一个灯,那么让下一个灯变绿,下一个等变绿之后,还会返回下一个变绿的灯
68         if(next !=null)
69         {
70             nextLamp = Lamp.valueOf(next);
71             
72             //测试用
73             System.out.println("绿灯从"+name()+"-------->切换为"+next);
74             
75             Lamp.valueOf(next).light();
76             
77         }
78         return nextLamp;
79     }
80 }
Lamp.java

-----------LampController.java-----------------

 1 package cn.itcast.interview.traffic;
 2 
 3 import java.util.concurrent.Executors;
 4 import java.util.concurrent.ScheduledExecutorService;
 5 import java.util.concurrent.TimeUnit;
 6 
 7 //灯的控制器
 8 public class LampController {
 9     //当前的灯
10     private Lamp currentLamp;
11     
12     //构造方法
13     public LampController()
14     {
15         //指定第一个灯并且当前的灯为绿的
16         currentLamp = Lamp.S2N;
17         currentLamp.light();
18         
19         //定义一个定时器,过一段时间,让灯变色
20         ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
21         timer.scheduleAtFixedRate(
22                 new Runnable()
23                 {
24                     public void run()
25                     {
26                         currentLamp = currentLamp.blackOut();//当前灯变黑
27                     }
28                 },
29                 10,
30                 10,
31                 TimeUnit.SECONDS);
32         
33     }
34 }
LampController.java

---------------MainClass.java-------------------

 1 package cn.itcast.interview.traffic;
 2 /**
 3  * 
 4  * @author Chen_zyan
 5  *
 6  */
 7 public class MainClass {
 8     /**
 9      * @param args
10      */
11     public static void main(String[] args)
12     {
13         //创建一个数组,将这12个方向存入
14         String[] directions = new String[]{
15                 "S2N","S2W","E2W","E2S",
16                 "N2S","N2E","W2E","W2N",
17                 "S2E","E2N","N2W","W2S"
18         };
19         
20         for(int i =0;i<directions.length;i++)
21         {
22             new Road(directions[i]);
23         }
24         new LampController();//控制器
25         
26     }
27 }
MainClass.java

 

posted on 2013-12-24 14:25  毛线球球  阅读(227)  评论(0编辑  收藏  举报

导航