黑马程序员7K---交通灯管理系统
交通燈管理系統
-----------?android培訓、java培訓、java學習型技術博客、期待與您交流!?------------
1.模擬實現銀交通燈管理系統邏輯
1.1 具體需求如下
(1)異步隨機生成按照各個路線行駛的車輛。
例如:
??????由南向而來去往北向的車輛 ---- 直行車輛
??????由西向而來去往南向的車輛 ---- 右轉車輛
??????由東向而來去往南向的車輛 ---- 左轉車輛
??????。。。
(2)信號燈忽略黃燈,只考慮紅燈和綠燈。
(3)應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。
(4)具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。
注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而后放行左轉車輛。
(5)每輛車通過路口時間為1秒(提示:可通過線程Sleep的方式模擬)。
(6)隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。
(7)不要求實現GUI,只考慮系統邏輯實現,可通過Logic方式展現程序運行結果。
具體實現線路圖
1.2 概述
方向說明:N(North)---北 ; S(south)-->南方;E(east)--> 東方 ;W(west)-->西方2為英文單詞to的意思N2E意思是由北到東。
對應線路:由上圖可知一共有12條線路。
而線路可分為直行線路、左轉線路、右轉線路。
直行線路有S2N,N2S,E2W,W2E;
右轉線路有N2W,E2N,W2S,S2E;
左轉線路有S2N,N2E,W2E,E2S;
其中由中國的交通情況可知,右轉是不需要交通燈訊號的,但為了面向對象編程思想,這里把右轉改為有交通燈訊號,且為常綠狀態。
而且根據交通知識可知,線程為一對一的關系,即每次放行時,只有一條線路與其相對應的線程通行,其他線路不通行。上圖同色線路為對應線路,由上圖可知其有4條一一對應線路。(S2N,N2S)、(E2W,W2E)(S2N,N2E) (W2E,E2S)
要求:
這四條一一對應的線程必須遵守線路上的交通燈指示運行與停止。而右轉之線路卻不用理會。
1.3 簡化線路
1)12條線路,每條線路作為一個對象;
2)每條線路由一個紅綠燈控制其通、停狀態;
3)右轉之紅綠燈設為常綠;
4)余下的8條線路(兩兩對應)分為四組
總結:程序只需考慮圖中的4條(同色)路線的紅綠燈的如何切換即可。
1.4 根據題目要求進行線路切換次序確定
1)將線路分為南北、東西兩部分,同方向等待車輛先放直行再放左轉車輛。
因為線路為兩兩對應關系,其實只需要考慮兩個方向的線程即可,即S(南)與E(東).
2) 從S方向出發的車有S2W和S2N這兩個方向的線路--->要求是先放直行后放左轉,所以S2N先施行;S2W后放行。
3)從E方向出發的車有E2W和E2S這兩個方向的線路---要求先放行直行再放行左轉,所以E2W先放行,E2S后放行。
總結:因為交通燈是循環切換的,所以從那個方向開始是沒有關系的,這里就由S開始循環切換。
可得
{2}3. 從S方向或者E方向那個開始都可以,因為這些線路的交通燈是循環切換的。因此這里面從S方向開始。While(true){
S2N(N2S)【1】---> S2W(N2E)【2】---> E2W(W2E)【3】 ---> E2S(W2N)【4】--->S2N(N2S)【1】 --->}
由切換關系可知,由這個交通燈程序只需要考慮兩條直線與兩條左轉線即可(4條線路,忽略同時進行的線路)。
1.5 面向對象的分析
1.5.1 類的提取
? ? 交通燈系統中需要用到路線、交通燈與車輛,而交通燈的亮滅不可能是自己決定,所以需要有一個類來控制其的亮滅,所以得有一個交通燈控制器類,所以可以將其分為這三個類 ----- 交通燈類、線路類、車輛類與交通燈控制器類。
1.5.2 模擬過程—車輛穿過一條線路的過程
? ? 首先應該先有一輛車,才能在線路上啟動運行,所以車輛類的實例應在線路類的實例中產生。一輛車產生后就在線路實例中運行。而且當這條線路上的交通燈為紅時,不得通行,這輛車前面有車輛也不得通行。。
1.5.3 類的分析
1.線路類的分析
成員分析:由上思想可得,車輛類一定要在線路的實例中生成,而線路中必然包括一個交通燈類的實例,這個實例是與線路一一對應的。所以可得每條線路的實例都包括相應的車輛與交通燈類的實例。
關系分析:由現實可知,一條交通線路上可以讓無數的車輛通過,而每條線路上只有一個交通燈在作用,當然這只是指這個實例上的十字路口。所以可得交通燈類與線路類是一一對應關系,而車輛類與線路類則是N對1的關系。
方法分析:
??? 在本實例中,汽車只是存在于通過線路時,即在通過線路時產生出現,而通過線路后則會自動銷毀。所以線路類中有車輛的減少與增加方法。汽車看到前面綠燈了,就可以通行了嗎,當然不是,在現實中,就算前面綠燈了,也需要看看自己前面有沒有車輛才可通過,當前面沒有車輛,且是綠燈時,方可通過,怎么判斷車輛位置是不是第一位呢,很明顯是用集合的下標表示為佳,所以線路類對象中汽車是以集合形式存儲的。
2.交通燈類分析
成員分析:
交通燈如現實上有三種顏色,但實際只是兩種顏色起作用,紅或綠,因為兩種顏色是相互切換的,即---紅燈亮時,綠燈滅;紅燈滅時,綠燈亮。所以只需要一種燈的狀態即可,用綠燈的亮滅表示其線路的通閉狀態。
方法分析:
如果線路問題,每個交通燈指揮著相應的線路的通閉,而每個交通燈都應該有其切換交通燈切換通閉的方法,即決定下一個通行的線路的切換。其順序就是對圖分析時的,先真行后左拐,再到另一方向上的直行,左拐。
具體分析:
有12條線路則有12個交通燈,但右拐之燈為常綠狀態,其他八條線路為一一對應狀態,則只需要4組燈的訊號即可。只需要在4組中各取出一個燈,對這4個燈進行依次輪流變亮,而其對應的燈也相應地一同變亮,燈的輪流變亮,則意味著,每一個交通燈需要知道自己的后一個交通燈,這樣才能達到輪流的效果,所以交通燈類中應該有一個變量來記錄自己的下一個交通燈。
3.車輛類分析
車輛類在這里只是一個體現車輛穿過線路的過程,也是并不需要車輛類中有相應的方法,所以車輛輛不需要單獨設計成一個對象,用一個字符串表示即可。----使用Java內建String類對象來替代自定義的車輛類。
4.交通燈控制器類分析
功能分析:需求:紅綠燈切換時間間隔可以是任意的,所以交通燈控制器類中的方法就應該有相應的時間屬性并且有設置該時間的方法。而且有切換交通燈的功能的方法。
2.程序編寫
2.1 交通燈類Lamp的程序編寫
1.由上例的分析可知Lamp類的功能應采用枚舉;
分析:12個交通燈對應著枚舉中的12個成員對象,Lamp類中的表示對應線路的屬性和下一條線路的屬性是一一對應關系的,這種一一對應關系可以采用String類型來替代Lamp類聚合的表示對應的Lamp類的實例和表示下一條交通燈的Lamp實例。
2. Lamp類代碼示例
1).Lamp的亮滅方法
增加讓Lamp變亮和變黑的方法:light和blackOut,對于S2N、S2W、E2W、E2N這四個方向上的Lamp對象,這兩個方法內部要讓相反方向的燈隨之變亮和變黑,blackOut方法還要讓下一個燈變亮。
2). Lamp類示例代碼
注:編寫程序時的包名:因這是面試題,而對方公司為軟通公司,所以我們把包名改為com.isoftstone.interview.traffic(面試小技巧);
package com.isoftstone.interview.traffic;/*** 每個Lamp元素代表一個方向上的燈,總共有12個方向,所有總共有12個Lamp枚舉元素。 * 程序代碼只需要控制每組燈中的一個燈即可:----括號中的表示該線路的交通燈對應的線路的交通燈* S2N(N2S)、S2W(N2E)、 E2W(W2E)、 E2S(W2N) -----受紅綠燈控制的交通燈* S2E(N2W) 和E2N(W2S) -----不受紅綠燈控制的交通燈* */ public enum Lamp { //每個枚舉元素各表示一個線路方向上的控制燈 //左轉的兩條主路+ 兩條直行線 ----初始化這些主路的燈光是滅的---Red 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), //四條右拐的路常綠 ---四個右轉彎方向的燈,因為其不受紅綠燈控制,所以可以假設它們總是綠燈 N2W(null, null, true), W2S(null, null, true), S2E(null, null, true), E2N(null, null, true); //當前燈的狀態,是否為綠 private boolean lighted =false; //當前線路交通燈的對應線路的交通燈 //一對一所以使用String的name替代 private String opposite =null; //當前線路交通燈的被切換到下一個交通燈 private String next =null; //一對一所以使用String的name替代 /*** 構造函數* @param opposite ----當前線路對應線路的交通燈的名字* @param next --------當前線路的下一條線路的交通燈的名字* @param lighted -----這條線路的交通燈初始化的時候被點亮(代表綠燈)*/ private Lamp(String opposite, String next, boolean lighted){ this.lighted =lighted; this.opposite =opposite; this.next =next; } /*** lighted屬性的Getter* @return---獲取當前線路的交通燈的狀態*/ public boolean isLighted() { return lighted; } /*** 點亮該燈----點亮表示將燈變成綠色的* 某個燈變綠時,它對應方向的燈也要變綠*/ public void light(){ this.lighted =true; //同時要點亮對應路段的交通燈 if(this.opposite !=null){ Lamp oppositeLamp =Lamp.valueOf(opposite); oppositeLamp.light(); } System.out.println(name()+" lamp is green, 下面可以看到6個方向看到汽車穿過!"); } /*** 滅掉該燈----也就是將該路段的交通燈變紅* @return----返回下一站切換的路燈*/ public Lamp blackOut(){ //當前燈變紅,對應方向的燈也變紅 this.lighted =false; //同時要滅掉對應路段的燈 if(this.opposite !=null){ Lamp oppositeLamp =Lamp.valueOf(opposite); oppositeLamp.blackOut(); } //點亮下一對應的燈 Lamp nextLamp =null; if(next !=null){ nextLamp=Lamp.valueOf(next); nextLamp.light(); System.out.println("綠燈從"+ name()+"--->切換為"+next); } return nextLamp; } }2.2 線路類Road程序編寫
1. 相應方法
1). 刪除方法 ------代表車輛穿過這條線路
每條路線每隔一秒都會檢查控制本路線的燈是否為綠,是則將本路線保存車的集合中的第一輛車移除,即表示車穿過了路口。
2). 增加車輛和刪除車輛的方法
??? 在上面的分析可知車輛的增刪不過是集合的增刪而已,所以這兩個方法不需要其實方法調用,可以直接放到Road類的構造方法即可。
3). Road類示例代碼
package com.isoftstone.interview.traffic; 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; /*** 每個Road對象代表一條路線,總共有12條路線,即系統中總共要產生12個Road實例對象。* 每條路線上隨機增加新的車輛,增加到一個集合中保存。* 每條路線每隔一秒都會檢查控制本路線的燈是否為綠,是則將本路線保存車的集合中的第一輛車移除,即表示車穿過了路口。*/ public class Road { //模擬該條路上的汽車集合 private List<String> vehichles =new ArrayList<String>(); //使用List接口 ---面相接口編程 //線路的線路名稱 ----- 實際聚合的是Lamp類實例 private String name; //實際通過這個name獲取這條線路一對一的Lamp類對象 /*** Road類的構造方法* @param name ----該條線路的線路名稱*/ public Road(String name){ this.name =name; //啟動另一個線程來創建該條路上的車輛 ---模擬車輛不斷隨機上路的過程,使用線程池,通過產生單個線程的方法,創建一個線程池 ExecutorService pool =Executors.newSingleThreadExecutor(); pool.execute(new Runnable(){ //通過for循環來模擬車輛的增加 ----隨機時間間隔生成一輛車 間隔不固定 @Override public void run() { for(int i=0; i< 1000; i++){ try { //按照一個隨機的時間間隔生成車輛 int randomTime =(new Random().nextInt(10)+ 1)*1000; Thread.sleep(randomTime); Road.this.vehichles.add(Road.this.name+"_"+ i); }catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); //啟動另一個線程來減少當前這條路上的車以模擬這輛車通過了這條路 ScheduledExecutorService timer =Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate( new Runnable(){ @Override public void run() { // TODO Auto-generated method stub if(vehichles.size() >0){ //查看當前路段對應的交通燈是不是已經亮了亮了的話讓該條路上的車輛通過 boolean lighted = Lamp.valueOf(Road.this.name).isLighted(); if(lighted){ System.out.println(vehichles.remove(0)+" is traversing!"); } } } }, 1, 1, TimeUnit.SECONDS); } }2.3 LampController程序編寫
1. 切換線路的方法
要求:每隔10s切換一下交通燈。
這個方法僅僅被使用一次之后即可,不需要被其他的方法調用。因此簡化程序,就直接放入到LampController類的構造方法即可。
2.LampController 類的設計規范
因為在整個交通燈系統中,交通燈控制器只能有一個,所以LampController類設計為單例模式。
3.LampController類的示例代碼
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit;/**** LampController類用來切換不同線路的交通燈每隔10秒將當前燈變紅,并按順序將下一個方向的燈變綠**/ public class LampController {private Lamp currentLamp;/*** 初始化第一盞要變綠的紅綠燈之后啟動新的線程進行線程切換* LampController設計成單例模式 StepI: 私有化構造方法*/private LampController() {// 指定第一盞亮的交通燈currentLamp = Lamp.S2N;currentLamp.light();// 設置定時器ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);timer.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {// 每隔10s切換下一盞亮的交通燈currentLamp = currentLamp.blackOut();}}, 10, 10, TimeUnit.SECONDS);}// 單例模式 ---- StepII:餓漢式構建全局訪問點public static final LampController lampController = new LampController(); }2.4 測試類MainClass程序編寫
?MainClass類的示例代碼
public class MainClass { public static void main(String[] args) { //實例化交通燈控制器實例 //在實例化LampController的過程中,會對相應道路的交通燈進行無限循環的切換 //-----啟動了新的線程進行切換 LampController lampController =LampController.lampController; //給出所有的方向 String[]directions =new String[]{ "S2N", "S2W", "E2W", "E2S", "N2S", "N2E", "W2E", "W2N", "N2W", "W2S", "S2E", "E2N" }; //實例化Road的過程 //---- 每一條路的new的過程中會查看這條路的交通燈的顏色并穿過馬路 ---- 一個新的線程 //---- 每一條路的自動增加車輛 ---- 有一個新的線程 for(int i=0; i< directions.length; i++){ new Road(directions[i]); } } }?-----------?android培訓、java培訓、java學習型技術博客、期待與您交流!?------------
總結
以上是生活随笔為你收集整理的黑马程序员7K---交通灯管理系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北邮计算机学院五组夏森,前辈种树 | 从
- 下一篇: autojs脚本apk安装器