交通燈管理系統

交通燈管理系統

一、需求分析。

在進行設計之前我們需要了解具體的十字路口交通規則:1、紅燈停綠燈行。2、對於十字路口的四個路口而言,“向右轉彎”始終是允許的即該方向始終保持綠燈。3、在十字路口處可以有12條行車路線可以選擇(如下圖所示),其中可以分爲5組,每一組中的一條路線是可行的則表示改組中的其他路線也是可行的。

二、系統設計。

1、  對象分析:系統中可以抽象出的對象爲:路、紅綠燈和燈控制系統。(在面向對象的分析過程中擁有數據的對象提供操作數據的方法)

2、  對象設計:

1)      路:

每條路線上會出現多輛車,路就是一個集合,路線上要隨機增加新的車,當在燈綠期間車通過路口需要一秒,即路集合中每秒減少一輛車,並返回減少車的名字。使用Road類表示路線,每個Road對象代表一個路線,前面已經分析了需要12條路線,即系統中要產生12個Road實例對象。

2)      紅綠燈:

每條路線每隔一秒都會檢查控制本路線的燈是否爲綠,一個燈由綠變紅時,應該將下一個方向的燈變綠。設計一個Lamp類來表示一個交通燈,每個交通燈都維護一個狀態:亮(綠),不亮(紅),每個交通燈要有變亮和變不亮的方法,並且能返回自己的狀態。

總共有12條路線,所以,系統中總共要產生12個交通燈。右拐彎的路線本來不受燈的控制,但是爲了讓程序採用統一的處理方式,故假設出有四個右拐彎的燈,只是這些燈爲常亮狀態。除了右拐彎方向的其他8條路線的燈,它們是兩兩成對的,可以歸爲4組,所以,在編程處理時,只要從這4組中各取出一個燈,對這4個燈依次變亮,與這4個燈方向對應的燈則隨之一同變化,因此Lamp類中要有一個變量來記住自己相反方向的燈對象,在一個Lamp對象的變亮和變黑方法中,將對應方向的燈也變亮和變黑。每個燈變黑時,都伴隨者下一個燈的變亮,Lamp類中還應該有一個變量來記住自己的下一個燈對象。

無論在程序的什麼地方去獲得某個方向的燈時,每次獲得的都是同一個實例對象,所以Lamp類改用枚舉來做顯然具有很大的方便性,永遠都只有代表12個方向的燈的實例對象。

3)      燈控制系統:設計一個LampController類,它定時讓當前的綠燈變紅。

三、系統實現。

1、  Road類設計與實現

                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 List<String>vehicles = newArrayList<String>();

  //定義一個變量存儲路線名

  private Stringname = null;

  public Road(String name){

      this.name = name;

      //模擬車上路的情況,假設該路線上有99輛車

      ExecutorServicepool = Executors.newSingleThreadExecutor();

     

      pool.execute(new Runnable() {

          @Override

          public void run() {

              //通過線程控制實現,路線每隔1-10秒增加一輛車

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

                  try {

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

                  }catch (InterruptedException e) {

                      e.printStackTrace();

                  }

                   vehicles.add(Road.this.name +"_" + i);

              }

          }

      });

       //每隔一秒檢查對應的燈是否爲綠,如果是綠的就輸出集合第一個,即第一輛車

      ScheduledExecutorServicetimer = Executors.newScheduledThreadPool(1);

      timer.scheduleAtFixedRate(

              new Runnable() {

                  @Override

                  publicvoid 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);

  }

}

2、  Lamp類的設計與實現

           publicenum  Lamp {

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 Lamp(String opposite,String next,boolean lighted){

       this.opposite = opposite;

       this.next = next;

       this.lighted = lighted;

  }

  //判斷燈狀態的部分

    private boolean lighted;

    //同屬於一個分組的路線

    private Stringopposite;

    //不同屬於一個分組的下一個路線

    private Stringnext;

    /*

    * 功能:判斷燈的狀態

    * 參數:無

    * 返回值:燈的狀態(true表示綠燈亮 false表示紅燈亮)

    */

    public boolean isLighted(){

      return lighted;

    }

    /*

    * 功能:將本路線的燈設爲綠燈狀態,同時將該路線的小組的燈設爲綠燈狀態

    * 參數:無

    * 返回值:無

    */

    public void light(){

       this.lighted =true;

        if(opposite !=null){

        Lamp.valueOf(opposite).light();

        }

        System.out.println(name() +" lamp is green,下面總共應該有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); 

         nextLamp.light();

      }

       //返回下一個燈變綠

       return nextLamp;

    }

}

3、  LampController 類的設計與實現

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public class LampControl {

  private LampcurrentLamp;

  public LampControl(){

       //剛開始讓由南向北的燈變綠;

        currentLamp = Lamp.S2N;

        currentLamp.light();

   

        //10秒燈的轉換時間

        ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);

        timer.scheduleAtFixedRate(

                new Runnable(){

                  @Override

                  publicvoid run() {

                      // 設定定時器

                      currentLamp =currentLamp.blackOut();

                  }},

                10,

                10,

                TimeUnit.SECONDS);

      }

}

四、測試類。

 public class TestClass {

    /**

     * 該類主要用於測試

     */

    public static void main(String[] args) {

        //定義一個數組存儲十字路口的各個路線名

        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 LampControl();

    }

}

輸出結果:

N2S lamp is green,下面總共應該有6個方向能看到汽車穿過!

S2N lamp is green,下面總共應該有6個方向能看到汽車穿過!

W2S_0 is traversing !

N2S_0 is traversing !

N2W_0 is traversing !

S2N_0 is traversing !

S2E_0 is traversing !

E2N_0 is traversing !

綠燈從S2N-------->切換爲S2W

N2E lamp is green,下面總共應該有6個方向能看到汽車穿過!

S2W lamp is green,下面總共應該有6個方向能看到汽車穿過!

S2W_0 is traversing !

N2E_0 is traversing !

S2W_1 is traversing !

W2S_1 is traversing !

S2W_2 is traversing !

E2N_1 is traversing !

N2W_1 is traversing !

N2E_1 is traversing !

S2W_3 is traversing !

E2N_2 is traversing !

S2E_1 is traversing !

W2S_2 is traversing !

N2E_2 is traversing !

N2W_2 is traversing !

綠燈從S2W-------->切換爲E2W

W2E lamp is green,下面總共應該有6個方向能看到汽車穿過!

E2W lamp is green,下面總共應該有6個方向能看到汽車穿過!

E2W_0 is traversing !

W2E_0 is traversing !

E2W_1 is traversing !

W2E_1 is traversing !

E2W_2 is traversing !

W2E_2 is traversing !

·······


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章