張老師交通燈

需求:

模擬實現十字路口的交通燈管理系統邏輯,具體需求如下:

 

  異步隨機生成按照各個路線行駛的車輛。

例如:

       由南向而來去往北向的車輛 ---- 直行車輛

       由西向而來去往南向的車輛 ---- 右轉車輛

       由東向而來去往南向的車輛 ---- 左轉車輛

       。。。

 

 信號燈忽略黃燈,只考慮紅燈和綠燈。

 

 應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制。

 

 具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。

注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而後放行左轉車輛。

 

  每輛車通過路口時間爲1秒(提示:可通過線程Sleep的方式模擬)。

 

  隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設置。

 

 不要求實現GUI,只考慮系統邏輯實現,可通過Log方式展現程序運行結果。

分析:

首先是他給的方向自己一會就暈了。

所以先按照一個方向 南 來分析

如圖所示 從南向北

                  從南向西

                  從南向東(右行可以忽略)

 

 

面向對象分析和設計

抽象出四類對象

問題1 .車在路上走 車不斷減少 車不斷減少的方法是 是車提供還是路提供 ????一點 誰對外提供數據,誰就提供對外訪問的方法。 車在路上 ,即路對外提供數據 所以

        路提供對外訪問的方法。

        紅綠燈 :1.總共12個燈 任何時候都不用new燈 所以用枚舉來解決

                       2. 三種 狀態 :自己的狀態 ,下一個燈,相反的燈。 即三個成員變量

     紅綠燈的控制器:當前燈是哪一個,有個定時器 ,時間已到就把當前的燈變紅。 變紅的方法得返回下一個燈

     路:每創建一個對象就指定他的名字,每一秒種路上就來一輛車

代碼:

package cn.itheima.interview.traffic;

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();
	}
}


package cn.itheima.interview.traffic;

public enum Lamp {
	S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2E","E2S",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 nextLamp,boolean lighted ){
 		this.opposite=opposite;
 		this.next=nextLamp;
 		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();//枚舉類型.valueOf把枚舉類型給它 他就給返回一對應枚舉類型的對象
			//opposite.light();
		}
		System.out.println(name() + " lamp is green,下面總共應該有6個方向能看到汽車穿過!");
	}
	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;
	}
}


package cn.itheima.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;

public class Road {
 private List<String> vehicles= new ArrayList<String>();//交通工具 因爲路上行駛不僅是小汽車
 private String name=null;//路的名字
 
 public Road(String name){//final 加final也能解決問題
	 this.name=name;
	 //產生100輛車 產生車也就是向路里面添加車那條路上的車
	 //Executors.newFixedThreadPool(1);或者
	ExecutorService pool= Executors.newSingleThreadScheduledExecutor();
	pool.execute(new Runnable(){

		@Override
		public void run() {
			for(int i=0;i<100;i++){
				 //讓車有時候多有時少
				 try {
					Thread.sleep((new Random().nextInt(10)+1)*1000);//1-10s的休息時間
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				 vehicles.add(Road.this.name+"_"+i);//某方向的某輛車
			 }
			
		}});
	//定時器的製作
	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();
						boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
						if(true){
							System.out.println(vehicles.remove(0)+"is traversing");;
						}
						
					}
					
				}
			},
			1,
			1,
			TimeUnit.SECONDS);
	 
 }
 
}


package cn.itheima.interview.traffic;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LampController {
	private Lamp currentLamp;
	public LampController(){
		currentLamp =Lamp.S2N;
		currentLamp.light();
		ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
				new Runnable() {
					
					@Override
					public void run() {
						currentLamp=currentLamp.blackOut();
						//currentLamp.
						
					}
				}, 
				10,
				10,
				TimeUnit.SECONDS);
	}
}


 

汽車看到自己所在路線對應的燈綠了就穿過路口嗎?不是,還需要看其前面是否有車,看前面是否有車,該問哪個對象呢?該問路,路中存儲着車輛的集合

 

根據張老師講的幾點 對我有用的幾點幫助的總結

個是大師們說的寫的代碼 起得名字非常得當 讓人看起了就懂 to=2   for=4

 

總結 自己犯的錯誤

1.內部類訪問 外部類的是name屬性 忘了this.name =name;

理解是外部類的屬性 而不是構造方法裏 傳過來的name 形參

2.當張老師把

Lamp nextLamp=null;
  if(next!=null){
   nextLamp=Lamp.valueOf(next);
   System.out.println("綠燈從" + name() + "-------->切換爲" + next);   
   nextLamp.light();
  } 這段代碼寫錯的時候自己已經意識到了 因爲自己也犯過類似的錯誤

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章