黑馬程序員java-交通燈管理系統《十》

                   ——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——

1,交通燈管理系統原理與分析

     首先明白它的工作原理,由於剛剛學車,大概明白交通燈是如何運作的,一般來說車右轉是默認不用看燈的,可以直接右轉的,

     但有時候當交通有箭頭顯示的時候又不一樣了,所以我們不考慮這種情況。那麼默認右轉燈是一直綠的。根據東南西北四個方向

     的車都有各自的三種路線,按道理,東南西北四個方向都有各自的三個方向的交通燈。從車方面考慮就有123x4)種路線,而

  對應的交通燈也有12個。現在單從一個方向去討論,比如說南(South)的方向,有三種情況,向右轉(即南到東方向)是不用理的,

  所以剩下直行(南到北)和左轉(南到西),假設直行的燈變綠了,則對應方向(北到南)也要變綠。直行的燈變紅後,則對應方向

 (北到南)也要變紅,而下一個燈左轉(南到西)就要變綠。其他方向也是這麼分析。

2,車和燈和燈控制的分析

     車:12種路線的車每個一段時間就在該路線添加一輛車,每秒檢查當前方向的燈是否變綠,如何變綠則當前方向的車就要刪除。

     燈:12種方向的燈,南(South)的方向,有三種情況,向右轉(即南到東方向)是不用理的,所以剩下直行(南到北)和左轉(南到西),

     假設直行的燈變綠了,則對應方向(北到南)也要變綠。直行的燈變紅後,則對應方向(北到南)也要變紅,而下一個燈左轉(南到西)就要變綠。所以基本上每種方向的燈要關聯兩個相關方向的燈。

     路:一共有12種路線,每個路線要要與相同方向的車對應。

3,面向對象思想設計交通燈系統

 (1)  :很明顯這是自定義的一種類,而最好的實現方式就是java的枚舉類來實現。

      每個Lamp元素代表一個方向上的燈,總共有12個方向,所有總共有12Lamp元素。

      有如下一些方向上的燈,每兩個形成一組,一組燈同時變綠或變紅,所以,程序代碼只需要控制每組燈中的一個燈即可:s2n,n2s  s2w,n2e  e2w,w2e

             e2s,w2n   s2e,n2w  e2n,w2s。上面最後兩行的燈是虛擬的,由於從南向東和從西向北、以及它們的對應方向不受紅綠燈的控制,

      所以,可以假想它們總是綠燈。所以一共有12lamp元素,實際上用到的是4組燈即四個方向的燈。lamp元素的構造方法裏應該有上面分析過

      的兩個相關聯方向的燈,還有一個自己燈狀態的值(false或者true)。燈應該有判斷自己燈狀態的方法,還有變綠和變紅的方法。

        燈的代碼如下:

public enum 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 String opposite;

/*當前燈變紅時下一個變綠的燈*/

private String next;

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個方向能看到汽車穿過!");

  }

  /**

 * 某個燈變紅時,對應方向的燈也要變紅,並且下一個方向的燈要變綠

 * @return 下一個要變綠的燈

 */

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;

}

} 

   (2)   路線:一共有12條路線,即要產生12個實例對象,每條路線上隨機增加新的車輛,而車就可以添加到一個集合中保存。

         以便處理。每條路線每隔一秒都會檢查控制本路線的燈是否爲綠,是則將本路線保存車的集合中的第一輛車刪除,即表示車穿過了路口。

                   路的類,路有自己路線的名字,而路線上的車的名字應該相同,都用字符串表示,如“s2n”,車輛不斷隨機上路的過程最好用線程來實現,

         而添加車輛的過程可以用for循環來實現。既然有添加車輛就要刪除車輛,因爲是通過每秒中檢查當前路線的燈是否爲綠的,所以也要用線程來實現,

         判斷當前路線的燈是否爲綠,如果爲綠,則刪除最前面的車輛,即第一部車。

          路的代碼如下:

public class Road {

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

   private String name =null;

public Road(String name){

this.name = name;

  //模擬車輛不斷隨機上路的過程

ExecutorService pool = Executors.newSingleThreadExecutor();

pool.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) {

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

  (3)  燈的控制類:每隔10秒將當前綠燈變爲紅燈,並讓下一個方向的燈變綠。所以也要通過線程來實現。

        代碼如下:

public class LampController {

private Lamp currentLamp;

public LampController(){

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

currentLamp = Lamp.S2N;

currentLamp.light();

/*每隔10秒將當前綠燈變爲紅燈,並讓下一個方向的燈變綠*/

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public  void run(){

System.out.println("來啊");

currentLamp = currentLamp.blackOut();

}

},
10,
10,
TimeUnit.SECONDS);

}
}

  (4)  啓動程序

public class MainClass {

  public static void main(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 LampController();

}
}

  總結:

         難點:

               1.交通系統的業務邏輯不容易瞭解。

               2.處理的各種交通情況比較多,需要用到枚舉類細化每個情況

               3.如何以面向對象的思想思考:如何設計類,以及類的屬性和行爲。類與類之間有什麼關係和相互影響。

 


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