黑马程序员.Android攻城狮.JAVA应用.3.1.交通灯管理系统

交通灯管理系统

---------- android培训、java培训、期待与您交流!----------

1、需求

        模拟实现一个十字路口的交通灯管理系统,具体需求如下:
        (1) 异步随机生成按照各个路线行驶的车辆。
                例如:
                由南向而来去往北向的车辆 ----直行车辆
                由西向而来去往南向的车辆 ----右转车辆
                由东向而来去往南向的车辆 ----左转车辆
                。。。
        (2) 信号灯忽略黄灯,只考虑红灯和绿灯。
        (3) 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
        (4) 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
        (5) 注意:
                (a) 南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
                (b) 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
                (c) 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

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

2、分析

        首先根据需求画出分析图:

黑马程序员.Android攻城狮.JAVA应用.3.1.交通灯管理系统_第1张图片

        经过对十字路口车辆运行分析可知,每个路口共有12条线路可以经过车辆,为了统一模型,假设每条线路上都有一个红绿灯进行控制,4个右转的路线上的灯为长绿,其他8条线路上的灯是两两成对,即有4组灯,我们只需分析这几组灯的切换状态即可,如下图所示,其中G代表该方向为绿灯,R代表红灯,

黑马程序员.Android攻城狮.JAVA应用.3.1.交通灯管理系统_第2张图片

3、面向对象分析

        由于在Java中一切描述事物都可以看做对象,那么经过以上的分析,我们将该系统中的事物划分为不同的类,其中有车辆类、道路类,交通灯类、控制红绿灯切换的类等。

        首先一个汽车类的对象询问前方路口的路是否允许通过,若路类上的灯为绿灯,则该条路允许车辆通过,否则不允许通过,但是前提是车前方没有其他车辆,这也需要向路询问,由于路上存放着车辆,而车辆保持着增加与减少车辆的状态,所以可以将路看做集合,将车看做集合中的元素,由于车辆是互不相同的,所以可以将其看做互不相同的字符串即可。

        面向对象设计把握一个重要的经验:谁拥有数据,谁就对外提供操作这些数据的方法。


4、编写所需的类

        (1) 灯类
        包括四个右转弯的灯在内,一个路口共有12个灯,当然这里与现实稍有区别的是每个灯有两种颜色状态——红与绿,而现实中每条路是有三个红、黄、绿颜色的灯,这里将其简化为只有一个灯可以显示出两种颜色,由于该灯类只有12个实例对象,那么就可以应用枚举来创建这12个灯实例对象。
        由于右转方向可假设为灯常绿,又相对两个方向的灯一般都是对称的,所以实际上变化的只有四个灯。编写灯类如下所示:

        (2) 灯控制器类
        灯控制器主要利用定时器来控制灯的红绿切换。
        Executors用法:
        (a) 创建一个线程池
        staticExecutorService newFixedThreadPool(int nThreads):
        创建一个有固定线程数的线程池,传入一个整数,nThreads表示要线程池内的线程数,返回一个新创建的线程池
        static ExecutorService newSingleThreadExecutor():
        创建一个只有一个线程数的线程池,不用传入参数,返回一个线程池(只有一线程)
        (b) 调用线程池的执行方法
        调用ExecutorService(其实是一个接口)的实现类ThreadPoolExecutor的方法
        public void execute(Runnable command):传入一个任务(Runnable的匿名内部类,覆写run方法),在将来某个时间执行给定任务
        拓展:创建带定时器的线程池
        static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):
        传入具有指定线程的数作为参数,创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行(理解为延迟固定时间后执行或者每个固定频率多次执行)
        返回的一个具有定时器的线程池对象,再介绍该对象的方法:
        ScheduledFuture<?> scheduleAtFixedRate(Runnable command,//任务
        long initialDelay,//首次执行的延迟时间
        long period,//连续执行的周期
        TimeUnit unit)//为上面的时间和周期指定单位,传入一枚举值
        调用这个方法使得该任务每隔一个时间周期,不断执行

        (3) Road类
        由以上分析可知,每个十字路口共有12个可行驶的方向,可以认为车辆可再这12条路上行驶,每个Road对象都有一个name成员变量来代表行驶路线,有一个vehicle集合来代表方向上的车辆。
        在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)。
        在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则移除车辆集合的第一辆车放入到车辆行驶的方向上去。


        (4) Directions类
        该类用于存放车辆,例如Road类中的对象r1路线为S2N,其中的vehicle.remove(0),存放到Directions对象的集合中,用于后续的显示使用。

        (5) WholeSystem类
        该类为主方法类,首先创建四个方向类的实例对象,然后创建12个Road类的对象,然后调用run()方法开始运行整个系统,其中还编写了函数用于显示每个交通灯的显示状态以及每个方向上的车辆增减情况。

5、运行结果

        下图为程序的运行结果,图中显示了每个交通灯的颜色状态,以及从各个方向上驶入四个方向上的车辆。

                                                   黑马程序员.Android攻城狮.JAVA应用.3.1.交通灯管理系统_第3张图片



6、总结

        该案例中包含的集合、多线程、定时器、枚举、内部类等等知识点,比较有综合性,并且对张老师的源代码有一些修改,增加了一些内容用于图形显示。



---------- Windows Phone 7手机开发、.Net培训、期待与您交流! ----------

你可能感兴趣的:(java,android,黑马程序员)