黑马程序员-JAVA学习之交通灯管理系统分析与实现

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

交通灯管理系统:

需求:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1. 异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 右转车辆
由东向而来去往南向的车辆 枚举来实现.枚举是一种特殊的(类).因为既有方法,字段,也有构造方法
代码实现如下:

//
package com.fylx.test;
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 opposite;
    private String nextlamp;
    private boolean isGreen;

    // 返回一个灯是否是绿色的属性
    public boolean isGrean()
    {
        return this.isGreen;
    }

    // 每个信号灯的对头灯,下一个要变绿的灯,这个灯是否绿色的
    Lamp(String opposite, String nextlamp, boolean isGreen)
    {
        this.opposite = opposite;
        this.nextlamp = nextlamp;
        this.isGreen = isGreen;
    }

    // 变绿的方法,如果有对头灯,对头灯的状态也要变绿
    public void turnGrean()
    {
        this.isGreen = true;
        System.out.println(this.name() + "方向的灯变绿了!");
        if (this.opposite != null)
        {
            Lamp.valueOf(this.opposite).turnGrean();
        }
    }

    // 变红的方法,如果有下一个对应的灯,则下一个灯要就绿,同时返回下一个灯
    public Lamp turnRed()
    {
        this.isGreen = false;
        System.out.println(this.name() + "方向的灯变红了!");
        if (this.opposite != null)
        {
            Lamp.valueOf(this.opposite).turnRed();
        }
        Lamp next = null;
        if (this.nextlamp != null)
        {
            next = Lamp.valueOf(this.nextlamp);
            Lamp.valueOf(this.nextlamp).turnGrean();
        }
        return next;
    }
}
//

下面我们我分析信号灯的控制器,由需求可以看出,控制器就是控制信号灯的交换时间的,只要弄一个定时器,在规定的时间和时间间隔内不断的让信号灯有条理的亮起来了变换就可以了
而且从上面的信号灯中我们可以看出,信号灯在变换的时候,会自动的触发其对应的对面的信号灯和左拐灯的变化,所以,在控制器中,我们只要控制一个灯的变红变绿就可以了,
代码实现如下:

//
package com.fylx.test;
import java.util.concurrent.*;
public class Controller
{
    //控制器当前要控制的信号灯
    private Lamp currentLamp;

    public Controller()
    {
        this.currentLamp = Lamp.S2N;
    }

    // 启用信号灯控制器,5秒后执行,并每过10秒变换信号灯的颜色
    public void on()
    {
        this.currentLamp.turnGrean();

        ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
        timer.scheduleAtFixedRate(new Runnable()
        {
            public void run()
            {
                currentLamp = Controller.this.currentLamp.turnRed();
            }
        }, 5, 10, TimeUnit.SECONDS);
    }
}
//

路线类的分析,由需求可知,路线类只管按信号灯的变化走车,车的增加和出现是异步随机生成的.且每辆车通过路口的时候都为1秒,能不能走车就看对应的信号灯是不是绿灯,而且路线的功能
与信号灯控制器没有关联,而于之关联的是信号灯,由于我们的信号灯是用枚举实现的,所以路线类直接保存信号灯的名称就可以了,由于路线上有车,所以路线这个类中也要添加相关车的代码
代码实现如下:

//
package com.fylx.test;
import java.util.*;
import java.util.concurrent.*;

public class Route
{
    // 定义一个交通工具
    private List<String> vechicles = new ArrayList<String>();
    // 线路的名称,要求和信号灯的名称对应
    private String name;
    // 随机算算器
    Random random = new Random();

    public Route(String name)
    {
        this.name = name;
        // 启动一个线程池,异步随机的生产交通工具
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(new Runnable()
        {
            public void run()
            {
                for (int i = 1; i < 1000; i++)
                {
                    try
                    {
                        Thread.sleep((random.nextInt(10) + 1) * 1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                    Route.this.vechicles.add(Route.this.name + "_" + i);
                }
            }
        });
        // 定义定时器,在1秒后执行,并且每1秒过一辆车
        ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
        timer.scheduleAtFixedRate(new Runnable()
        {
            public void run()
            {
                if (vechicles.size() > 0)
                {
                    Lamp lamp = Lamp.valueOf(Route.this.name);
                    if (lamp.isGrean())
                    {
                        System.out.println(vechicles.remove(0) + "安全通过了!");
                    }
                }
            }
        }, 1, 1, TimeUnit.SECONDS);

    }
}
//

现在我们来模拟一个测试环境,在这个环境中,有路线,有信号灯控制器,因为信号灯是枚举,不用在这里实例化,直接在控制器里面关联一个信号灯就可以了.
测试代码如下:

//
package com.fylx.test;
public class Test
{
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        String[] lamps = new String[] { "S2N", "S2W", "E2W", "E2S", "N2S", "N2E", "W2E", "W2N", "S2E", "E2N", "N2W", "W2S" };

        for (String lamp : lamps)
        {
            // 根据信号灯,实例化对应的线路
            new Route(lamp);
        }
        // 生产一个信号灯控制器,并同时启用
        new Controller().on();
    }
}
//

在这个系统的设计过程中,难的并不是代码实现,而是业务分析,如果业务逻辑分析清楚了,代码实现也就好写了.

时间: 2024-08-03 18:42:51

黑马程序员-JAVA学习之交通灯管理系统分析与实现的相关文章

黑马程序员-JAVA学习日记-数组YNPB

黑马程序员学习笔记黑马程序员编程基础数组培训.培训.期待与您交流!数组:是存储同一种数据类型的的集合,也叫容器:特点:是数组中每个元素都有索引从开始:数组的定义式:数据类型数组名数据类型元素个数:数据类型数组名数据类型元素个数:如:数据类型数组名数据类型元素数据类型数组名元素如:如果元素确定就用这一种:数组中有一个属性:获取数组中的元素个数,即数组的长度:中的内存机制:栈:存储局部变量,一般定义在函数内的变量成为局部变量:特点:当内存中数据操作完成后,所占空间会自动释放栈内存堆:是通过创建的实体

黑马程序员——JAVA学习笔记十(IO)

1,    可以从其中读入一个字节序列的对象成为输入流,可以向其中写入一个字节序列的对象就做输出流.这些字节序列的来源地可以是文件,也可以是网络连接或者内存块.抽象类InputStream和OutputStream构成了I/O层次的基础.因为字节流不便于处理以Unicode存储的信息,所以有了Writer和Reader抽象类,这些从其中继承的类都是读入和写入基于2个字节的Unicode码元,而不是单个字节.   2,    InputStream 与OutputStream: abstract

黑马程序员——JAVA学习笔记十四(高新技术三)

10 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代

黑马程序员——JAVA学习笔记五(异常)

1,     异常:是在运行时期发生的不正常情况. 在java中用类的形式对不正常情况进行了描述和封装对象.描述不正常的情况的类,就称为异常类. 以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性. 其实异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述. 不同的问题用不同的类进行具体的描述.比如角标越界.空指针异常等等. 问题很多,意味着描述的类也很多,将其共性进行向上抽取,形成了异常体系. 不正常情况分成了两大类: Throwabl

黑马程序员-JAVA学习之银行业务调度系统分析与实现

--------android培训.java培训.期待与你交流!-------- 银行业务调度系统 模拟实现银行业务调度系统逻辑,具体需求如下:1 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口.2 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费.电话费之类业务的客户).3 异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户 :普通客户 :快速客户 = 1 :6 :3.4 客户办理业务所需时间有最大值和最小值,在该

黑马程序员-JAVA学习之反射以及Class类的常用方法

--------android培训.java培训.期待与你交流!-------- Class类 Class 类的实例表示正在运行的 Java 应用程序中的类和接口.枚举是一种类,注释是一种接口.每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象.基本的 Java 类型(boolean.byte.char.short.int.long.float 和 double)和关键字 void 也表示为 Class 对象. Class 没有公共构造方法

黑马程序员Java学习日记之 Java-其他类型

OK , 就绪, 第一篇博客开撸 ~ android培训.java培训.期待与您交流! 先听了毕姥爷激情澎湃的其他类型 ,从这里开始入手吧 : (一)System类  System类代表系统类,系统的属性和方法都放在该类.System类是一个final类, 它不能被初始化,,即System类中的属性和方法都是static的,可以直接陪调用.System的成员变量有 out,in, err 即标准输入输出和错误输入(流),常用到的System类的方法有下面几个: a. arraycopy方法 :p

黑马程序员——JAVA学习笔记十一(文件操作File)

为了很方便的代表文件的概念,以及存储一些对于文件的基本操作,在java.io包中设计了一个专门的类——File类. 在File类中包含了大部分和文件操作的功能方法,该类的对象可以代表一个具体的文件或文件夹,所以以前曾有人建议将该类的类名修改成FilePath,因为该类也可以代表一个文件夹,更准确的说是可以代表一个文件路径. 1.创建文件 1)boolean java.io.File.createNewFile() throws IOException用来创建文件,如果文件存在,创建失败,返回fa

黑马程序员——JAVA学习笔记十二(高新技术一)

 1,    静态导入: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package com.solaire.enhance; import static java.lang.Math.max;  //import   语句可以导入一个类或某个包中的所有类 //import static  静态导入 JDK5以后才有.语句导入一个类中的某个静态方法或所有静态方法 //无名包和有包名中的类在一起,没有package,则为无名包. //一个类