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

来源:互联网 发布:淘宝旺铺价格 编辑:程序博客网 时间:2024/05/21 02:50
------- android培训、java培训、期待与您交流! ----------

黑马程序员—交通灯管理系

一、案例需求:

Ø 异步随机生成按照各个路线行驶的车辆。

例如:

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

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

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

      。。。

 

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

 

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

 

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

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

 

Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

 

Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

 

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

 

二、根据案例分析,得出以下案例模式图如下:

1、 总共有12个路线,

 

南—北

北—南

东—西

西—东

 

南—西

北—东

东—南

西—北

 

南—东

东—北

北—西

西—南

三、用面向对象的设计思想

     用面向对象的设计思想来剖析案例,可以得到的对象有:路,灯的控制器,红绿灯。路负责车的过往,红绿灯负责控制灯的状态,使得路可以根据灯的当前状态来控制哪个方向上可以通行,而灯的控制器用于控制灯在某个方同上维持一定时间后,把当前红绿类的状态改为红灯并把下一个路线的灯设为绿灯。

四、路的逻辑代码设计

----------------------------------------------------------------------------------------------------------

package com.qdn.audition.trifficlight;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public class Road {

        private String roadName;

        private List<String> carsInRoad = new ArrayList<String>();

 

        public Road(String roadName) {

                  this.roadName = roadName;

                  ExecutorService executorService = Executors.newSingleThreadExecutor();

                  executorService.submit(new Runnable() {

 

                           @Override

                           public void run() {

                                    for (int i = 0; i < 1000; i++) {

                                              try {

                                                       Thread.sleep((new Random().nextInt(10) + 1) * 1000);

                                              } catch (InterruptedException e) {

                                                       // TODO Auto-generated catch block

                                                       e.printStackTrace();

                                              }

                                              carsInRoad.add("" + Road.this.roadName + "上有"

                                                                + Road.this.roadName + i + "经过");

                                    }

                           }

                  });

                  ScheduledExecutorService scheduledExecutorService = Executors

                                    .newScheduledThreadPool(1);

                  scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 

                           @Override

                           public void run() {

                                    if (carsInRoad.size() > 0) {

                                              Light l=Light.valueOf(Road.this.roadName);

                                              boolean isLighted =l.isLighted();

                                              if (isLighted) {

                                                       System.out.println(carsInRoad.remove(0));

                                              }

                                    }

                           }

                  }, 1, 1, TimeUnit.SECONDS);

        }

}

----------------------------------------------------------------------------------------------------------

        首先在路这个对象的构造函数上产生一条线程,随机构造出1000个车,然后再产生一个定时器,在定时器中,不断的判断这路上的灯是否为绿灯,如果是,就从路中车的集合中每一秒钟移过一辆车,

五、灯的逻辑代码:

----------------------------------------------------------------------------------------------------------

package com.qdn.audition.trifficlight;

 

publicenum Light {

  //East-

  //Western西

  //South

  //North

  //东西方向

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

  //东南方向

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

  //南北方向

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

  //南西方向

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

  //与上对"东西方向"的反方向

  W2E(null,null,false),

  //与上对"东南方向"的反方向

  N2S(null,null,false),

  //与上对"南北方向"的反方向

  W2N(null,null,false),

  //与上对"南西方向"的反方向

  N2E(null,null,false),

  //北西方向

  N2W(null,null,true),

  //西南方向

  W2S(null,null,true),

  //南东方同

  S2E(null,null,true),

  //东北方同

  E2N(null,null,true);

  

  private Stringopposite;

  private Stringnext;

  privatebooleanisLighted;

  private LightnextLight;

  

  publicboolean isLighted() {

     returnisLighted;

  }

  private Light(String opposite, String next,boolean isLighted) {

     this.opposite = opposite;

     this.next = next;

     this.isLighted = isLighted;

  }

  publicvoid setGreeLight()

  {

     isLighted=true;

     if(opposite!=null)

        Light.valueOf(opposite).isLighted=true;

  }

  publicvoid setRedLight()

  {

     this.isLighted=false;

     if(opposite!=null)

        Light.valueOf(this.opposite).isLighted=false;

     nextLight=Light.valueOf(this.next);

     System.out.println("绿灯从" + name() + "-------->切换为" + next);

     nextLight.isLighted=true;

  }

  public Light getNextLight() {

     returnnextLight;

  }

}

----------------------------------------------------------------------------------------------------------

     使用enum类型根据需求设计出12种路灯的状态,构造函数传递了某状态相反方向上的状态,下一个路类的状态,和路灯是否为绿灯。比如如东本方向上能通行,那么西东方方向也能通行,下一个是东南方向;东南方向能通行,那么西北方向也能通行,下一个方向是南北方向;南北方赂能通行,那么北南方向同时也能通行,下一个方向是南西方向;南西方向能通行,那么北东方同也同时能通行。也就是说,只要确定一边的通行情况,就可以知道对应的另一个方向也能确定其状态。

        在此enum中,setGreeLight方法用于设置其路的类和其路相反对应的灯为绿灯. setRedLight方法用于提供给灯的控制器系统,在某一时间隔后,将类设为红灯,并给出下一个路的绿灯,getNextLight用于给灯的制控制器系统返回当前为绿灯的路。方便在下一次时间隔到来时,继续设置下一种灯为绿灯。并返回此灯,依次类推。

六、灯的控制器代码逻辑:

----------------------------------------------------------------------------------------------------------

package com.qdn.audition.trifficlight;

 

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public class Controller {

        Light courrentlight=Light.E2W;

        public Controller()

        {

                  courrentlight.setGreeLight();

                  ScheduledExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(1);

                  scheduledExecutorService.scheduleAtFixedRate(

                                    new Runnable(){

 

                                              @Override

                                              public void run() {

                                                       Controller.this.courrentlight.setRedLight();

                                                       Controller.this.courrentlight=Controller.this.courrentlight.getNextLight();

                                                       Controller.this.courrentlight.setGreeLight();

                                              }},

                                    20,

                                    20,

                                    TimeUnit.SECONDS);

                  

        }

}

----------------------------------------------------------------------------------------------------------

主要是用于产生一个定时器,控制灯状态的生命周期。如上述代码为20秒后,从当前的灯中得到下一个灯,并把当前的灯设为红灯后,打开下一个灯为当前绿灯,当路在检测到此绿灯时,就开始通行。

七、交通灯的启动器:

        首先是实例化此十字路口12条交通路线,启动它位的红绿灯检测模块,当发现检测到的灯为绿灯时,路的过车就会启动。至到灯为红灯为止。

----------------------------------------------------------------------------------------------------------

     package com.qdn.audition.trifficlight;

 

publicclass MainCLass {

  /**

   *@param args

   */

  publicstaticvoidmain(String[] args) {

     

     /*产生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 Controller();

  }

}

八、总结:

        此交通灯的关键点在于灯和路配合,路为12条路,也就是说有12个实例对象,分别有自已的运行线程,都在检测交通灯的状态,只要发现自已的灯为绿灯就开始通行(打印在控制台)。而灯又和灯的控制器完美结合,灯的状态交由控制器来控制灯在各各方向上红绿状态,使得各个路上的检测中,只有其中两条路能通行,这样,只要控制器控制当前的灯和下一个灯,就可以实现交通灯案例了。

        通过此案例,以后在再项目时,在分析案例时,一定要以面向对象的思惟去考虑问题,把各个对象的职责划分清楚,有可能的话,画图帮助辅助分析。比如上面的案例,如果不画图的话,凭空想象是很难发现这些要素的(12条路),当我们发生这些要素后,就分清了各个对象的职责划分了,车大了十字路口上行过,那么对象应该是路,而不是车,所以路有车过往的职责。灯的职责就是提供状态控制职责。控制器对象的职责是控制灯状态的改变。所以此案例所涉及对象就有:灯,路,控制器