您的位置:首页 > 职场人生

【黑马程序员】交通灯管理系统_学习笔记

2014-06-23 00:18 483 查看
------- android培训java培训、期待与您交流! ----------

首次接触这种比较大的工程,或者说是系统,整个过程还是学到了很多东西的。

首先是拿到项目的思路问题,一直苦于不知道从0开始如何下手,看了张孝祥老师的视频之后真是受益良多。

1、张老师说了,拿到项目先画图,不要空想,多画图是有好处的,事实证明,画图能使思路更清晰,思考也能更加直观,下面是跟着老师画的交通灯管理系统的图。



从图中可以分析出来,需要走的路线一共有12条,这也是之后在主方法中需要new出来的对象。

2、对参与事物进行分析与分类,对事物的本质进行分析。该项目中,需要分析的有四个事物,分别是灯、灯的控制器、汽车、路。

灯:4个路口12个灯,不允许new对象,用枚举(往其中写十二个元素),保证只有12个对象,不能单独创建对象,只有四个灯有逻辑,其他灯跟随这4个灯变化。

在这里,我们不考虑黄灯的情况,只考虑简单的红绿两种灯的情况。

灯的控制器:一个灯绿了,对面的灯跟着绿了,并且返回给下一个灯,下一个灯就红了。

汽车:灯变绿,前面没有车,才能走,是否有车要问路。不需要研究车的属性和走的过程,所以汽车是字符串而不是对象。

路:12条路线,一个集合,集合中很多车,有增加车辆和减少车辆的方法,变绿灯了则取走最前端的一个车。

以上是对参与事物的分析,于是接下来,便可以根据图和各事物的分析进行代码的编写了。

3、写代码的过程中,命名很重要,同时,需要严谨的进行,否则时候检查会增加很多工作量。

package cn.itheima.interview.traffic;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Road {
List<String> vechicles = new ArrayList<String>();

private String name = null;
public Road(String name)
{
this.name = name;

ExecutorService pool = Executors.newSingleThreadExecutor();//Executors线程管理工具
//newSingleThreadExecutor()只有单个线程的线程池
pool.execute(new Runnable(){ //实现了一个Runnable对象
public void run(){
for(int i=1; i<1000; i++){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vechicles.add(Road.this.name + "_" + i);
}
}
});

//定时器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//调度池
timer.scheduleAtFixedRate(
new Runnable() {

@Override
public void run() {
if(vechicles.size()>0)
{
boolean light = Lamp.valueOf(Road.this.name).isGreen();
if(light)
System.out.println(vechicles.remove(0)+" is traversing!");
}

}
},
1,
1,
TimeUnit.SECONDS
);

}
}


在这段路的代码中,我们讲交通工具作为一个字符串属性存在了集合中,并且,定义了一个定时器,指定灯换了之后开始的时间,并且这个时间是用额外的线程进行操作。
package cn.itheima.interview.traffic;

/*
* S2N,S2W,E2W,E2S,
N2S,N2E,W2E,W2N,
S2E,E2N,N2W,W2S;
*
*
* */
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 Lamp(String opposite, String next, boolean light)
{
this.opposite = opposite;
this.next = next;
this.light = light;
}

private boolean light;
private String opposite;
private String next;

public boolean isGreen(){
return light;
}

public void setGreen()
{
this.light = true;
if(opposite!=null)
Lamp.valueOf(opposite).setGreen();
System.out.println(name() + " is green , 接下来有6个方向有汽车穿过");
}

public Lamp setRed()
{
this.light = false;
if(opposite!=null)
Lamp.valueOf(opposite).setRed();

Lamp nextLamp = null;

if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "---------->" + next);
nextLamp.setGreen();
}
System.out.println(name() + " is red");

return nextLamp;
}
}
这段代码是灯的枚举,因为考虑到灯整条线路只有12种情况,为了限定好数目并不允许额外生成对象,所以使用枚举这一项技术。
以方向的方式定义枚举的元素,并且,其中拥有现在的亮灯方向,下一个亮灯方向,以及现在的亮灯情况,而且,其中还写有setGreen和setRed方法,用于设置灯的状态,同时在setRed中设置返回值给下一个灯。
package cn.itheima.interview.traffic;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LampController {
private Lamp currentLamp;

public LampController(){
currentLamp = Lamp.S2N;
currentLamp.setGreen();

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable() {

@Override
public void run() {
currentLamp = currentLamp.setRed();

}
},
10,
10,
TimeUnit.SECONDS);

}

}

这是灯的控制器,首先定义一个灯的现在状态,并且构造函数默认S2N灯是绿的,下面提供定时器,以10秒为间隔将绿灯变红。
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"
};

for(int i=0; i<directions.length; i++)
{
new Road(directions[i]);
}

new LampController();
}

}

最后是主函数的代码,因为12个对象很多,所以不考虑 一个个去new,于是想到先将这些字符串以数组的形式储存起来,然后用for循环定义,12个对象都建立之后就调用灯的管理器,开始进行代码的检验了。

通过这次张孝祥老师的交通灯视频,我了解了拿到题目或者项目之后首先该做的是什么,另外还对面向对象的思想又理解了一些,这对我以后的学习非常有帮助。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: