交通灯管理系统

    技术2025-10-19  5

    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)