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