黑马程序员 张老师-面试题交通灯管理系统学习笔记

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ------------------------------------------ 

交通灯管理系统

通过看张老师的视频讲解学习到啦:

1当我们拿到这个项目的时候,对于该怎么入手。如何想我们不能凭空想象,我们要在现实生活中找到他的原形。就如这个项目我们可以想象

我们自己最为熟悉的某个十字路口红绿灯的情况。

2当我们找到啦这样一个模型,我们也不能凭空在大脑里想,灯是怎么控制,车市怎么运行。因为这样我们很容易造成大脑一片混乱。

所以我们可以借助画图很直观的体现出来。我们的道路是有12条路线的。

S2NS2WE2WE2S
N2SN2EW2EW2N
S2EE2NN2EE2S
如果不是画图我们还不一定能清晰的知道原来是有12条线。

3现在我们到啦面向对象的分析和设计

那我们要定义些什么对象呢。一开始我想,既然路上有灯,有车,车里有人。是人看到啦红绿灯来控制车的行驶。哈哈,一听张老师的讲解,我才了解

到我们平时看到的想到的大都不是现象的本质。我们在没有很好的了解面向对象设计思想时,我们会过多的强调车这一对象而把路这一对这项目有着

关键性的对象产生啦忽略。从这里我体验到,掌握好面向对象的设计思想很重要,远远比写代码重要的多。学好啦面向对象的设计思想,可以一针见

血的通过事件的现象看到事情的本质。从而我们能找到我们真正需要定义的对象是什么,在这一项目中是,路,灯,灯的控制器。

4我们是如何来定义路这一对象的呢?

我们定义对象是通过它的属性和行为来确定的,

路的定义

每条路线上都会出现多辆车,路线上要随机增添新的车,在绿灯期间,还要每一秒钟减少一辆车。

设计一个Road类来表示路,每一个Road对象代表一条路,总共12条路线,即系统总共要产生12个Road实例对象。

每条路上随机增加新的车辆,增加到一个集合中保存。

每条路线每隔一秒钟都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。

灯的定义

每条路线每隔一秒都会检查控制本路线的灯是否为绿,一个灯由绿变红时,应该将下一个方向的灯变绿。

设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或不亮(红)每个交通灯要有变亮和变黑的方法,并且能返回自己的亮

黑状态。

总共12条路线,所以,系统中公要产生12个交通灯。右拐路线本不受灯的控制,但是为啦让程序才用统一的处理方式。故假设出游4个右拐弯的灯

,只是这些灯为长亮状态,即有不黑。

除了右拐弯方向的其他8条路线灯,它们是两两成对的,可以归为4组。所以在编程处理时,只要从这4组中个取一个灯对这4个灯依次轮回变亮。

与这4个方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象变亮和变黑方法中,将对

应方向的灯也变亮和变黑。每个灯变黑时,都伴随着下一个灯变亮。Lamp类中还用一个变量记住自己的下一个灯。无论在程序的什么地方去

获得某个方向的灯时,每次获得的都是相同的一个实例对象,所以Lamp类该用枚举来作,显然具有很大的方便性,永远都只代表12个方向的灯

实例对象。

设计一个LampController类,它定时让当前的绿灯变红灯。

5程序代码的编写

List   list=new ArrayList(  );//这加做面向接口编程比较专业。

在路的设计上,

生成车辆定义啦一个控制器,车辆的移动用到啦定时器的思想。

了解内部类和线程在这项目中的广泛应用。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TrafficLamp {
 
 public static void main(String[] args) {
  String []lamps=new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
  for(String lamp:lamps)
  {
   new Road(lamp);
  }
         new LampController();
 }
}
//公路:用于产生车辆
//以及车在绿灯是通过路口
class Road
{
 private String name=null;
 private List<String> vehicles=new ArrayList<String>();
 public Road(String name)
 {
  this.name=name;
  
  //产生车辆
  Executors.newSingleThreadExecutor().execute(new Runnable()
  {
   public void run()
   {
    for(int i=1;i<1000;i++)
    {
     try{
     Thread.sleep((new Random().nextInt(10)+1)*1000);
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     vehicles.add(Road.this.name+"_"+i);
    }
    
   }
  });
  
  //车在绿灯是通过路口
  Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
    new Runnable()
    {
     public void run()
     {
      if(vehicles.size()>0)
      {
       boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
       if(lighted)
       {
        
        System.out.println(Road.this.name+"方向上的"+vehicles.remove(0)+" is traversing");
       }
      }
     }
    },
    1,
    1,
    TimeUnit.SECONDS);
 }
 
 }
//交通灯
enum Lamp
{
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
//枚举并设计需要循环操作的4个代表灯及元素,指定出对应相反的灯和下一个灯,从一个方向开始循环
 N2S("S2N","N2E",false),N2E("S2W","W2E",false),W2E("E2W","W2N",false),W2N("E2S","N2S",false),
//与上边路线和指示灯相反的4个对应的灯,其对应灯和下一个灯为空,已经指定了方向,只要参与循环即可
 S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
 //是本次循环方向中所有向右转弯的路线,不受红绿灯的控制,所以初始化一直为ture代表绿灯
 private Lamp(String opposite,String next,boolean lighted)
 {
  this.opposite=opposite;
  this.next=next;
  this.lighted=lighted;
 }
 
    private String opposite;
    private String next;
    private boolean lighted;
    public boolean bSwitch=true;
   
    //灯的状态是绿还是红
    public boolean isLighted()
    {
     return this.lighted;
    }
   
    //等变绿,同时相对方向的等也变绿
    public void light()
    {
     this.lighted=true;
     if(opposite!=null)
     {
      if(bSwitch)
      {
      Lamp.valueOf(opposite).bSwitch=false; 
      Lamp.valueOf(opposite).light();
      System.out.println(name()+" lamp is green.下面总共应该有6个方向能看到车");
      }
      //this.bSwitch=true;
     }
     
    }
    //等变红,同时相对方向上的等也变红,而且让next变绿
    public Lamp blackOut()
    {
     this.lighted=false;
     if(opposite!=null)
     {
      if(bSwitch)
      {
      //Lamp.valueOf(opposite).bSwitch=false; 
      Lamp.valueOf(opposite).blackOut();
      System.out.println("绿灯从"+this+"切换到"+next);
      
      }
      //this.bSwitch=true;
     }
     
     Lamp nextLamp=null;
     if(bSwitch){
     
     if(next!=null)
     {
      nextLamp=Lamp.valueOf(next);
      
      nextLamp.light();
      
     }
     }
     return nextLamp;
     
     
    }
   
}
//灯控制器
class LampController
{
    private Lamp currentLamp;
    public LampController()
    {
    currentLamp=Lamp.S2N;
    currentLamp.light();
   
    Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
      new Runnable()
      {
       public void run() //执行
       {
        currentLamp=currentLamp.blackOut();
       }
      },
      10,         //等待执行的时间
      10,         //执行后等待时间
      TimeUnit.SECONDS);//计时单位
    }
}
//主函数
public class MainClass {
   public static void main(String[] args){
   String[] directions={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","W2S","N2W"};
 for(int i=0;i<directions.length;i++)
{
   new Road(directions[i]);
}
   new LampControllor();
}
}

-------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ------------------------------------------ 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值