java中交通灯管理系统_java案例--交通灯管理系统学习
一、需求分析
剛接到一個項目或者面試題(總之是一個相對比較復雜的問題時),應該對認真閱讀問題的
要求和描述,并通過對這些的分析進行抽象,通過一個個對象的方式來考慮自己的程序該
怎么寫。所以,首先來看看需求,再設計出對象。
交通燈管理系統
模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:
? 異步隨機生成按照各個路線行駛的車輛。
例如:
由南向而來去往北向的車輛 ---- 直行車輛
由西向而來去往南向的車輛 ---- 右轉車輛
由東向而來去往南向的車輛 ---- 左轉車輛
。。。
? 信號燈忽略黃燈,只考慮紅燈和綠燈。
? 應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。
? 具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。
注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而后放行左轉車輛。
? 每輛車通過路口時間為1秒(提示:可通過線程Sleep的方式模擬)。
? 隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。
? 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。
通過閱讀以上文檔,在交通燈這一十字路口中,我想到了以下幾個對象:
1、交通燈
2、汽車
3、路
但在視頻的學習中我得知了還有這么一個對象:
4、交通燈的控制器
既然有了這些對象,那么該如何設計,這些對象應該具有些什么功能?這些問題如果沒有
面向對象的設計思想,是很難從眾多的關系中,設計出一個類所具有的屬性和功能來的。
所以程序設計要先掌握一些面向對象的設計思想。視頻中通過一個概念和一些例子來幫助
我了解面向對象的一個重要原則:
*誰擁有數據,誰就對外提供操作這些數據的方法。
并通過以下例子來掌握這個重要原則:
1、人在黑板上畫圓。
人在黑板上畫圓,里面有3個對象:人、黑板、圓。有一個動作:畫圓。
那么畫圓這個方法該由誰來提供呢?因為畫圓需要圓的屬性:半徑、圓心等,所以根據
*誰擁有數據,誰就對外提供操作這些數據的方法這個原則。畫圓的方法應該歸到圓這個
類上。而黑板則應該設計成為存儲各種集合的類。
2、列車司機緊急剎車。
這里有兩個對象:車和司機。車本身具有離合器,所以應該由車提供剎車的方法。人本身
不具備剎車的能力,但是可以向車傳遞信息。
3、售貨員統計收獲小票的金額。
因為小票上有商品的價格信息,所以統計金額的方法該由小票來提供。
4、你把門關上了。
門本身具有鎖等屬性,所以關門的方法也該由門來提供。
5、“兩塊石頭磨成一把石刀,石刀可以砍樹,砍成木材,木材做成椅子”,
stone
stonenKnife = StoneFactory.creatKnife(stone1,stone2)
timber = stoneknife.cut(tree)
chair = charfactory.makeChair(timber)
學習了以上的思想,那么在設計交通燈管理系統的時候,就比較容易理解一個類該提供哪些
方法了。
燈:應該提供變紅變綠的方法,還提供該燈處在綠或者是紅的狀態的方法,黃燈因為不影響
車輛的通行,所以忽略不計。
路:路上有車輛的集合,應該有增加和減少車輛的方法(車輛通過路口,就相當于減少了)。
所以路應該根據燈的狀態來決定是否減少集合中的車輛。所以路應該有兩個屬性:車和燈。
因為題目不要求描述車過路的具體狀況,所以車類可以用String來表示,就不用單獨設計了。
燈的控制器:提供一個方法,該方法定時地讓燈變綠和變紅。
二、根據分析的出的結果來設計相應的類
*燈(Lemp)類的設計:
通過日常生活知道,一個十字路口總共對應了12條路線:
s2n,n2s (這里2的意思是to)
s2w,n2e
e2w,w2e
e2s,w2n
s2e,n2w
e2n,w2s
現實中不是每天路線都有燈,但為了讓系統更統一,每天路線上都設計了對應的燈。
其中s2e,n2w,e2n,w2s這4個燈是右轉的燈,在現實中是不存在的,因為現實中無論何時都能
進行右轉彎,但為了統一性,右轉燈可以設計為總是綠的。
(s2n,n2s)(s2w,n2e)(e2w,w2e)(e2s,w2n)每兩盞燈各為一組,因為如果其中一盞變綠,對應方
向的燈也會跟著變綠。所以控制器每次只要控制其中一盞就可以,那么控制器總共只要4盞燈。
也就是只控制這四盞:s2n,s2w,e2w,e2s,。當s2n變紅以后,應該把下一盞燈變綠讓控制器得
到其對象,也就是s2w,依次類推,就模擬了燈依次變紅變綠的效果。
因為總共只有12盞燈,使用了枚舉類型。以后的設計中如果遇到只需要使用固定幾個
對象的時候,就可以考慮使用枚舉。
燈的代碼:Lamp.java
package com.isoftstone.interview.traffic;
public enum Lamp {
//控制器需要控制的4盞燈
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 String opposite; //對應方向的燈
private String next; //下一個方向的燈
private boolean lighted; //是否綠燈
//構造方法為枚舉元素實例化
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
public boolean isGreen(){
return lighted;
}
//提供變綠的方法,當本燈變綠時,對應方向的燈也應該變綠
public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light(); //通過對象名得到對象本身,進行遞歸調用
}
System.out.println(name() + " lamp is green,下面總共應該有6個方向能看到汽車穿過!");
}
//提供變紅的方法,當本燈變紅,對應方向的燈也變紅,同時把下一盞變綠的燈返回
public Lamp red(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).red();
}
Lamp nextLamp = null;
if(next != null){
Lamp.valueOf(next).light();
nextLamp = Lamp.valueOf(next);
System.out.println("綠燈從" + name() + "-------->切換為" + next);
}
return nextLamp;
}
}
*燈控制器(LampContriller)的設計:
首先燈控制器和燈有對應關系,所以里面應該有個屬性表示燈,那么該屬性用Lamp
類的實例對象來表示。接著控制器應該讓s2n,s2w,e2w,e2s這四盞燈的其中一盞變
綠,過一段時間后讓這盞燈變紅。然后定時地讓燈變紅邊綠。這就需要建立一個獨立
的線程,并使用定時器類來完成定時操作,java本身提供了這樣的類。
燈控制器代碼:LampController.java
package com.isoftstone.interview.traffic;
import java.util.concurrent.*;
public class LampController {
//因為要對Lamp進行操作,那么提供操作Lamp的方法的它一定有Lamp屬性
private Lamp currentLamp ;
public LampController(){
this.currentLamp = Lamp.S2N;
currentLamp.light();
//使用java類讓燈定時10秒后變紅,然后讓下一盞燈變綠
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currentLamp = currentLamp.red();
}
},
10, //10個單位后執行
10, //每隔10個單位執行1次
TimeUnit.SECONDS); //單位為秒
}
}
*路(Road)的設計:
路上有很多車,而且有燈,使用一個集合來存放車,因為需要模擬車輛不斷隨機上路
的過程,那么就需要隨機時間往集合里添加車,如果本條路線上的燈變綠了,就要放
行集合中的車輛。所以要產生兩條線程,一個是增加車的線程,一個是檢查是否綠燈
,如果是綠燈就減少集合中車輛的線程。
路的代碼:Road.java
package com.isoftstone.interview.traffic;
import java.util.*;
import java.util.concurrent.*;
public class Road {
private List vechicles = new ArrayList();
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).isGreen();
if(lighted){
//remove返回值就是移除的對象
System.out.println(vechicles.remove(0) + " is traversing !");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
*一個系統的三個元素都設計好了,應該由一個含有main方法的類來綜合使用它們
因為有12條路線,應該產生12個Road的對象,然后啟動LampController。
mainClass:
package com.isoftstone.interview.traffic;
public class MainClass {
public static void main(String[] args) {
//產生12個方向的Road
String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
for(int i=0;i
new Road(directions[i]);
}
//啟動控制器
new LampController();
}
}
總結:代碼很少,很精簡,但對整個交通燈系統進行的抽象很到位,很成功地模擬了
整個系統從開始到運行的各種狀態,以及對象間的各種關系。燈類的設計很巧妙。如果
是交給我來寫,這樣的代碼是寫不出來的,不過一切都是從模仿開始的。希望通過多
學習一些設計的案例,來加強自己面向對象設計的能力。
總結
以上是生活随笔為你收集整理的java中交通灯管理系统_java案例--交通灯管理系统学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java emailbuilder 样式
- 下一篇: flyway java使用,如何使用fl