交通灯管理系统

1.       逻辑分析

1)  12条线路,先分析由南向北,由南向西,由东向西和由东向南的四条线路,

2)  右行线路不受交通灯控制,其他线路对称

3)  流程:

  绿灯:先走南-北的车,再走南-西的车  西-东:红灯

南—北 红灯                                西-东:绿灯:先走西-东的车,再走西南的车

 

2.       面向对象分析

面向对象的本质:谁拥有数据,谁就拥有对外操作这些数据的方法。

道路

车灯管理系统

建立实例情景

1)车在道路上,用集合存储

2)车灯是12个不变的对象,用枚举类型,和路线同名

3)车灯管理系统用来控制交通灯亮灭的时间间隔

4)在实例中定义12个方向的线路,开启交通灯控制系统

 

 

3.Road类分析:车存储在路的集合里,路名和车名是一样的。在构造方法里建立一个线程池(只有一个线程),每隔1-10秒把车辆添加到当前绿灯的路上。得到一个定时器连接池(内部只有一个定时器)。每1秒刷新1次,如果该方向上有车?如果该车前边的车灯是绿的,则移除当前方向的第一辆车。

Road练习代码:

package org.it315.interview.traffic;

import java.util.*;

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> vechicles=new ArrayList<String>();

    //路的名字

    private String name=null;

    public Road(String name)

    {

       this.name=name;

       //建立一个人只有一个 线程的线程池

    ExecutorService pool=Executors.newSingleThreadExecutor();

    //产生某个方向上一个车的队列

    pool.execute(new Runnable(){

 

       public void run() {

           String []directions=new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};

           int ranWay=new Random().nextInt(12);

           for (int i =1; i < 1000; i++) {

             

              try {

                  //产生一个1-10秒的随机时间

                  Thread.sleep((new Random().nextInt(10)+1)*1000);

              } catch (InterruptedException e) {

                  e.printStackTrace();

              }

             //产生一辆车,添加到集合中

               vechicles.add(directions[ranWay]+"_"+i);

           }

          

       }

      

    });

    ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);

    timer.scheduleAtFixedRate(new Runnable()

    {

 

       public void run() {

           //如果路上有车的话

           if (vechicles.size()>0) {

                //如果灯是绿的话

              boolean lighted=Lamp.valueOf(Road.this.name).isLighted();

              if (lighted) {

                  String carName=vechicles.remove(0);//移除第一个元素

                  System.out.println(carName+" is traversing");//打印该车信息

              }

           }

             

           }

 

      

            },

           1,

           1,

           TimeUnit.SECONDS);

 

   

    }

   

}

4.Lamp类分析:

@因为交通灯类里确定有12个对象,所以该类用枚举类型。

@枚举出12条线路,其中主控4条线路交通灯的两灭,主控线路控制对称的4条线路,右拐的4条线路恒定为绿灯。

@有三个属性,当前灯的亮灭,对称线路的名称,下一条线路的名称

@构造方法为这三个属性赋值

@对等的操作有三个方法,返回当前灯的状态。把灯点亮。灭掉当前灯,点亮下盏灯,并返回下盏灯的对象。

Lamp编码练习:

package org.it315.interview.traffic;

 

public enum Lamp {

   

   

    //主控灯

    S2N("N2S",false,"S2W"),S2W("N2E",false,"E2W"),

    E2W("W2E",false,"E2S"),E2S("W2N",false,"S2N"),

    //被控灯

    N2S(null,false,null),N2E(null,false,null),

    W2E(null,false,null),W2N(null,false,null),

    //右行灯,恒为绿

    S2E("N2W",true,"S2E"),E2N("W2S",true,"E2N"),

    N2W(null,true,null),W2S(null,true,null);

   

    private Lamp(String opposite,boolean lighted,String next)

    {

       this.opposite=opposite;

       this.lighted=lighted;

       this.next=next;

    }

   

    //灯是否为绿

    private boolean lighted;

    //返回灯的状态

    public boolean isLighted()

    {

       return lighted;

    }

    //把灯变绿

    public void light(){

       this.lighted=true;

       if (opposite!=null) {

           Lamp.valueOf(opposite).light();

       }

       System.out.println(this.name()+"灯绿了!!,下面共有六个方向能看到汽车穿行");

    }

    //把灯变红

    public Lamp blackOut()

    {

       this.lighted=false;

       if (opposite!=null) {

           Lamp.valueOf(opposite).blackOut();

       }

       Lamp ligthNext=null;

       if (next!=null) {

           ligthNext=Lamp.valueOf(next);

           System.out.println("绿灯从"+name()+"-->切换为"+next);

           ligthNext.light();

       }

       return ligthNext;

      

    }

    //与灯同时为绿的对应方向

    private String opposite;

    //灯变红时下一个变绿的灯

    private String next;

   

}

5.LampController逻辑分析

@有一个当前线路的属性

@在构造方法中初始化最开始的线路,并点亮改方向上的灯。

@每隔XX调用灭灯的方法,返回下一盏灯的对象

@如果直行线,和拐弯可以时间分段是不是更好?时间比较紧,代码存在问题

package org.it315.interview.traffic;

 

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public class LampController {

    private Lamp currentLamp;//定义一个当前灯的对象

    private int i=0;//定义一个全局运行变量,用来控制代码块的执行

    public LampController()

    {

       currentLamp=Lamp.S2N;

       currentLamp.light();//初始化最开始亮的灯

       ScheduledExecutorService timer=Executors.newScheduledThreadPool(2);

    while(true)

       {

           if (i%2==0) {

              timer.schedule(new Runnable()//开启偶数时间段进程

              {

 

                  public void run() {

                     currentLamp=currentLamp.blackOut();

                  }

                 

              },

              5,

                TimeUnit.SECONDS);

              System.out.println("你好,我停了5");

           }else {

               timer.schedule(new Runnable()//开启奇数时间段进程

              {

 

                  public void run() {

                     currentLamp=currentLamp.blackOut();

                    

                  }

                 

              },

              2,

                TimeUnit.SECONDS);

              System.out.println("你好,我停了2");

           }

            i++;

       }

    }

}

 

思考:if块内的定时器不被主线程打断的话,程序就能正常执行,可是怎么做呢?求指教

6.MainClass分析

@定义一个线路名称的数组,匿名实例化线程对象

@匿名实例化LampController对象,在其构造方法内直接运行交通灯控制的方法。

package org.it315.interview.traffic;

 

public class MainClass {

 

 

    public static void main(String[] args) {

       //定义线路名称的数组

       String []directions=new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};

       //Road循环实例对象

       for (int i = 0; i < directions.length; i++) {

           new Road(directions[i]);

       }

       //实例化交通灯管理系统

       new LampController();

 

    }

 

}

总结:多谢代码多分析,学到高人的1/10就心满意足了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值