交通灯管理系统思路总结
一.思路明確
交通燈系統模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:
--異步隨機生成按照各個路線行駛的車輛。
例如:
???????由南向而來去往北向的車輛?----?直行車輛
???????由西向而來去往南向的車輛?----?右轉車輛
???????由東向而來去往南向的車輛?----?左轉車輛
???????。。。
--信號燈忽略黃燈,只考慮紅燈和綠燈。
--應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。
--具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。
注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而后放行左轉車輛。
--每輛車通過路口時間為1秒(提示:可通過線程Sleep的方式模擬)。
-- 隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。
--不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
難點:
1.如何理清思路?
2.如何建立具體對象?
3.如何想到線程問題?
一.應該對生活有很深的體驗,和熟練的編程思路,此時畫圖法幫助很大。
總共有12條路線,為了統一編程模型,可以假設每條路線都有一個紅綠燈對其進行控制,右轉彎的4條路線的控制燈可以假設稱為常綠狀態,另外,其他的8條線路是兩兩成對的,可以歸為4組,所以,程序只需考慮1S2N?2S2W?3E2W?4E2S?這4條路線的控制燈的切換順序,這4條路線相反方向的路線的控制燈跟隨這4條路線切換,不必額外考慮。
找到突破口很重要!盡量優化條件。
二.建立具體對象
誰擁有數據,誰就對外提供操作這些數據的方法。
開始構思一下有哪些對象:路線-->車, ?紅綠燈--->紅綠燈的控制系統
汽車看到自己所在路線對應的燈綠了就穿過路口嗎?不是,還需要看前面是否有車,看前面是否有車,該問哪個對象呢?該問路,路中存儲著車輛的集合,顯然路上就應該有增加車輛和減少車輛的方法了。(面向對象設計把握一個重要的經驗:誰擁有數據,誰就對外提供操作這些數據的方法。)再看題目,我們這里并不要體現車輛移動的過程,只是捕捉出車輛穿過路口的過程,也就是捕捉路上減少一輛車的過程,所以,這個車并不需要單獨設計成為一個對象,用一個字符串表示就可以了。在1中初步設想的對象就減少了一個。這個項目只需要3個對象即可。
在這個十字路口,有且僅有12盞紅綠燈,因此紅綠燈可以用枚舉來實現。其中右轉的四盞燈常綠,剩下的八盞燈可以分為4組。因此只需要考慮4盞燈的紅綠變化。
- 路線(Road)?
- 紅綠燈 (Lamp)
- 紅綠燈的控制系統 ?(LampController)
Road 類: public class Road { private List<String> vehicles = new ArrayList<String>(); //用這個List來保存這條路上的車 private String name = null; //這條路線和燈的名字public Road(String name) //構造方法,每創建一條路時都必須為它命名 { this.name = name; //啟動一個線程,不停地向這條路上增加車輛 ExecutorService pool = Executors.newSingleThreadExecutor(); //線程池的作用pool.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { try { Thread.sleep((new Random().nextInt(10)+1) * 1000); //每1到10秒內.nextInt(10) 10以內,不包括10} catch (InterruptedException e) { e.printStackTrace(); } // vehicles.add(name + "_" + i);這樣寫編譯會報錯,因為這里訪問的是這個構造方法里的局部變量。在匿名內部類里訪問局部變量,這個局部變量必須用final修飾符修飾 所以這里有兩種改法:1.加final修飾符,2.在這里訪問外部類的成員變量。 vehicles.add(Road.this.name + "_" + i); //訪問外部類的成員變量。 } } }); //啟動一個定時器 ,這是<span style="font-family: 宋體; ">ScheduledExecutorService 里面的定時方法</span>ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate( //這個方法需要四個參數 new Runnable() //如果是綠燈,并且路上有車,就移走一輛車 { @Override public void run() { if (vehicles.size()>0) { boolean lighted = Lamp.valueOf(Road.this.name).isLighted(); // if (true == lighted) 低能的表現啊。 if (lighted) { System.out.println(vehicles.remove(0) + "is traversing ! "); } } } }, 1, //參數2:多少時間后開始執行任務 1, //參數3:每隔多少時間執行一次任務 TimeUnit.SECONDS //參數4:前面這兩個時間的單位 ); } }Lamp類: 難點: 1.S2N、S2W、E2W、E2N這四個方向上的Lamp對象依次輪詢變亮 2.燈綠,相反方向的燈要變綠,燈變紅,對應方向的燈也要變紅,并且下一個方向的燈要變綠 package com.isoftstone.interview.traffic; public enum Lamp { S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false), //有業務邏輯的4個燈 N2S(null,null,false) ,N2E(null,null,false) ,W2E(null,null,false) ,W2N(null,null,false) , //和上面一一對應的4個燈 S2E(null,null,true) ,E2N(null,null,true) ,N2W(null,null,true) ,W2S(null,null,true) ; //常綠的4個燈 private boolean lighted; //用來表示燈的狀態。true為綠燈,false為紅燈 private String opposite;//這里要把相對應的Lamp用字符串代替,是因為S2N(N2S)這種寫法可能會報錯,Cannot reference a field before it is defined. private String next; //當前燈變紅時,下一盞應該變綠的燈 private Lamp(String opposite,String next,boolean lighted) { this.opposite = opposite; this.next = next; this.lighted = lighted; } 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個方向能看到汽車穿過 !"); //這六個方向是指:當前路線, //當前路線的對應路線,以及4個常綠路線。 } // 讓當前燈變紅的方法,同時檢查當前燈有沒有對應燈,若有,需將對應燈也變紅。然后,將當前燈的下一盞燈變綠。 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; } }
LampController類 重要:單例,定時器 public class LampController { private Lamp currentLamp; public LampController() { currentLamp = Lamp.S2N; //最開始設定S2N這個燈是綠的 currentLamp.light(); ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate( new Runnable() //每隔10s將當前燈變暗,同時將currentLamp變為下一盞燈。 { @Override public void run() { System.out.println("燈控定時器"); currentLamp = currentLamp.blackOut(); } }, 2, 2, TimeUnit.SECONDS ); } }
MainClass類 產生路線,放進集合中去。 public class MainClass { public static void main(String[] args) { //new出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."誰擁有數據,誰就對外提供操作這些數據的方法"
總結
以上是生活随笔為你收集整理的交通灯管理系统思路总结的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Kettle的设计
- 下一篇: python三角网格代码_Python
