——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——
1,交通燈管理系統原理與分析
首先明白它的工作原理,由於剛剛學車,大概明白交通燈是如何運作的,一般來說車右轉是默認不用看燈的,可以直接右轉的,
但有時候當交通有箭頭顯示的時候又不一樣了,所以我們不考慮這種情況。那麼默認右轉燈是一直綠的。根據東南西北四個方向
的車都有各自的三種路線,按道理,東南西北四個方向都有各自的三個方向的交通燈。從車方面考慮就有12(3x4)種路線,而
對應的交通燈也有12個。現在單從一個方向去討論,比如說南(South)的方向,有三種情況,向右轉(即南到東方向)是不用理的,
所以剩下直行(南到北)和左轉(南到西),假設直行的燈變綠了,則對應方向(北到南)也要變綠。直行的燈變紅後,則對應方向
(北到南)也要變紅,而下一個燈左轉(南到西)就要變綠。其他方向也是這麼分析。
2,車和燈和燈控制的分析
車:12種路線的車每個一段時間就在該路線添加一輛車,每秒檢查當前方向的燈是否變綠,如何變綠則當前方向的車就要刪除。
燈:12種方向的燈,南(South)的方向,有三種情況,向右轉(即南到東方向)是不用理的,所以剩下直行(南到北)和左轉(南到西),
假設直行的燈變綠了,則對應方向(北到南)也要變綠。直行的燈變紅後,則對應方向(北到南)也要變紅,而下一個燈左轉(南到西)就要變綠。所以基本上每種方向的燈要關聯兩個相關方向的燈。
路:一共有12種路線,每個路線要要與相同方向的車對應。
3,面向對象思想設計交通燈系統
(1) 燈:很明顯這是自定義的一種類,而最好的實現方式就是java的枚舉類來實現。
每個Lamp元素代表一個方向上的燈,總共有12個方向,所有總共有12個Lamp元素。
有如下一些方向上的燈,每兩個形成一組,一組燈同時變綠或變紅,所以,程序代碼只需要控制每組燈中的一個燈即可:s2n,n2s s2w,n2e e2w,w2e
e2s,w2n s2e,n2w e2n,w2s。上面最後兩行的燈是虛擬的,由於從南向東和從西向北、以及它們的對應方向不受紅綠燈的控制,
所以,可以假想它們總是綠燈。所以一共有12個lamp元素,實際上用到的是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.如何以面向對象的思想思考:如何設計類,以及類的屬性和行爲。類與類之間有什麼關係和相互影響。