黑马程序员之Java--交通灯管理系统需求分析及总结

来源:互联网 发布:广告牌生成器软件 编辑:程序博客网 时间:2024/05/22 12:03
------- android培训、java培训、期待与您交流! ----------

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下: 

Ø  异步随机生成按照各个路线行驶的车辆。

例如: 由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。 

Ø  信号灯忽略黄灯,只考虑红灯和绿灯。 

Ø  应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。 

Ø  具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。 

Ø  每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。 

Ø  随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。 

Ø  不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


根据上述需求,先画个图,了解下方向

从图中分析下:
总共有12条路线,为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制灯可以假设称为常绿状态,另外,其他的8条线路是两两成对的,可以归为4组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

面向对象分析与设计
​1、每条路线都会出现很多车,路线上要随机增加很多车,在灯绿期间还要每秒减少一辆车
      那么就设计一个Road类,每个Road对象就是一条路线,总共12条,故系统中要产生12 个实例对象
      每条路线上要随机增加车辆,故需要一个队列集合存储车辆,先来的车辆,先开走
      路线上会定期每秒检查对应的灯是否绿,是则从集合中移除一辆车,表示穿过路口。这里就有个定时器,定时操作
2、交通灯都有各自的状态,灯绿或灯红,且有12个方向的灯
   那么就设计一个Lamp类,表示交通灯,有个状态lighted,值为true或false,表示灯绿或灯红。灯还有个变绿和变红的方法总共有12条路线,所以,系统中总共要产生12个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方     法,故假设出有四个右拐弯的灯,只是这些灯为常亮状态,即永远不变黑。   除了右拐弯方向的其他8条路线的灯,它们是两两成对的,可以归为4组,所以,在编程处理时,只要从这4组中各取出一个灯,对这4个灯依次轮询 变亮,与这4个灯方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象的变亮和变黑方法中,将对应方向的灯也变亮和变。每个灯变黑时,都伴随者下一个灯的变亮,Lamp类中还用一个变量来记住自己的下一个灯。
  无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类改用枚举来做显然具有很大的方便,永远都只有代12个方向的灯的实例对象。 需要个交通灯控制器,控制灯定时更换状态

于是就有了以下类:
1、Road类:表示路线,路线上有很多车辆,使用队列集合存储
package com.heima.traffic;import java.util.Random;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * 路线:每条路线都有随机的车辆,每次绿灯行驶 * @author Administrator * */public class Road {//队列,存储车辆使用private Quere<String> list = null;//路线方向private String name ;public Road(String name){this.name  =name;list = new Quere<>();//定时模拟车辆在路上Executors.newSingleThreadExecutor().execute(new Runnable() {@Overridepublic void run() {for(int i=1;i<1000;i++){try {//从1秒到10秒中随机产生再乘以1秒,也就是1秒到10秒Thread.sleep((new Random().nextInt(10)+1)*1000);} catch (InterruptedException e) { e.printStackTrace();}list.add(Road.this.name+"_"+i); //存储车辆}}});//每秒检查当前路线上的灯,绿灯就通车Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {//获取当前路线上的灯Lamp currentLamp = Lamp.valueOf(Road.this.name);//判断灯是否绿if(currentLamp.isLight()&&!list.isEmpty()){//开走一辆车String car = list.remove();System.out.println(car+" is traffic ……");}}},1,1, TimeUnit.SECONDS);}}

2、Quere类:表示队列,存储车辆的集合
package com.heima.traffic;import java.util.LinkedList;/** * 队列,存储车辆的集合类,先进先出 * @author Administrator * */public class Quere<T> {private LinkedList<T>  list = null;public Quere(){list = new LinkedList<>();}public void add(T t){list.addFirst(t);}public T remove(){return list.removeLast();}public boolean isEmpty(){return list.isEmpty();}}


3、Lamp:表示交通灯,有变亮和变黑的方法,变黑后要返回下个变亮的灯,共有12个灯,除去右转的常绿灯,还有8个灯,共4组
/** * 交通灯,共12个,右转的有4个是常绿,还有8个是相对应的,也就是有4组灯 * @author Administrator * */public enum Lamp {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 oppive;//下一个灯private String nextLamp;//灯的状态private boolean lighted = false; private Lamp(String oppive ,String nextLamp,boolean lighted){this.oppive = oppive;this.nextLamp = nextLamp;this.lighted =lighted;}/** * 是否绿灯 * @return */public boolean isLight(){return lighted;}/** * 设置绿灯 */public void light(){this.lighted = true;if(oppive!=null){ Lamp.valueOf(oppive).light(); }System.out.println(name()+"变为绿灯");}/** * 设置红灯,返回下一个绿灯 * @return */public Lamp blaceout(){this.lighted = false;if(oppive!=null){  Lamp.valueOf(oppive).blaceout(); }Lamp nextlam = null;if(nextLamp!=null){nextlam = Lamp.valueOf(nextLamp);nextlam.light();System.out.println("绿灯由"+name()+"转为"+nextLamp);}return nextlam;}}

4、LampController: 表示交通灯控制器,定时控制灯的状态
package com.heima.traffic;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;/** * 交通灯控制器 * @author Administrator * */public class LampController {private Lamp currentlamp;private LampController(Lamp lamp){this.currentlamp = lamp;this.currentlamp.light();}/** * 控制交通灯变换状态,每隔10秒更换一次 */public void start(){Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {//判断灯是否绿if(currentlamp.isLight()){//设置灯为红且返回下一个绿灯currentlamp = currentlamp.blaceout();}}},10, 10, TimeUnit.SECONDS);}private static LampController instance = new LampController(Lamp.S2N);public static LampController getInstance(){return instance;}}

5、测试类
package com.heima.traffic;public class MainClass {/** * @param args */public static void main(String[] args) {String[] lamps = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};//循环构造出12条路线for(int i = 0;i< lamps.length;i++){new Road(lamps[i]);}//控制器开始运行 LampController.getInstance().start();}}

视频中张老师在Road类中用ArrayList集合存储车辆,我单独把存储集合的类封装成队列,队列具有先进先出,即排在前面的车先走,不用判断前面是否还有车


------- android培训、java培训、期待与您交流! ----------
0 0
原创粉丝点击