在交通系统的学习中,我认为代码是一个方面,最重要的是要学到面对一个项目时工作的一个思路。 比如在这里,没有比画图说明最好的方法了,一个十字路口,四个方向来车,每个方向又有3条路线,那一共就是12条路线,12条线对应12个灯。 但是这12条线中右转的可以一直设为绿灯。而且相对的两个灯要保持同颜色。 那么在参照实际情况时会发现一共是对 4条线路进行循环:哪4条呢?
从 南 来: 1、正直到北,2、左转到西 。 从 东 来 :3、正直到西,4、左转到南
那么 从 北 来的 和 从 西 来 的就可以分别的 这四个相对应。
在项目的开发过程中一定要建立起::面向对象的思想。 而且面向对象的原则:谁拥有数据,谁就对外提供操作数据的方法。
在使用技术时要尽量使用新技术,因为既然新技术被提出来就是有价值的。
在这个例子中,有这些东西: 灯、灯控制器、路、车。 如果将车看成一个类的话,在这题中没有实际意义,因为没有对车进行具体操作,而是对道路进行操作,车进入路线,离开路线。 那么就将路看成一个类。
接着就是灯:先将黄灯忽略,让灯先具有 亮 和不亮来表示 绿灯 和红灯。 又因为一个路线对着一个灯,所以 灯名和路线名借助同一命名系统。
知识点:命名,假如从 南 来的车,那么就有三个方向, 南到北:South to North ---> s to n------>S2N, 同样其余两个:S2W, S2E,
那么一共有的路线就是: S2N,S2W,E2W,E2S, N2S,N2E,W2E,W2N, S2E,E2N,N2W,W2S
开始对类进行描述:
Road:
将路上的车看成一个字符集合中的一个字符,有进有出,定义一个存放车辆的集合 private List<String> vechicles=new ArrayList<String>()
这里的车应该是随机过多少时间会添加进来,那么就涉及到线程的 暂停计数,当涉及一个线程时, 原技术中 有两种创建线程的方法。 而这里 张老师运用了新技术,Executor 接口,对线程进行批量操作的方法。
ExecutorService pool=Executors.newSingleThreadExecutor();
随机一个时间段后,增加一个车。
在通过Executor设定一个计时器, ScheduledExecutorService timer=Executors.newScheduledThreadPool(1) ;
当灯是lighte (绿灯)时,假设 1 秒,车减少一个。
对于灯
使用jdk 1.5之后的新技术:枚举。
首先 灯类型中要具有的属性: 当期灯的状态(lighted)、自己对应的那个灯(opposite),当期灯成红灯后 的下个绿灯(next),这里的next 成为绿灯之后就变成了当前灯(currentLamp)
代码如下:
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), // 这里定义12个灯,前四个作为来循环操作的, 中间四个刚好是前四个灯的 相对应灯
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true); //后四个就是四个又转弯的,可以一直为 绿灯。
//三个参数:相对的灯,下个灯,此时自己的状态 这里 中间四个灯要求::不再有相对应的灯, 因为他们本身就是别人的对应,此时如果再对应别人的话
private Lamp(String opposite,String next,boolean lighted) // 就造成 了死循环。
{
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
private boolean lighted;
private String opposite; // 三个私有字段 ,这里将 opposite 和 next 的属性都定义成了String 类型,因为在 枚举给第一行的四个对象初始化时,里面传递的对象
private String next; //还没初始化,会造成编译不通过。
public boolean isLighted()
{
return lighted;
}
public void light()
{
this.lighted=true;
if(opposite!=null)
Lamp.valueOf(opposite).light();
}
public Lamp blackOut() // 这里当一个灯 变成 红灯之后 ,要返回一个 绿灯
{
this.lighted=false;
if(opposite!=null)
{
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp=Lamp.valueOf(next);
if(next!=null)
{
nextLamp.light();
}
return nextLamp;
}
}
灯控制器
灯控制器 主要是对当前灯进行控制: private Lamp currentLamp;
在构造函数中 先指定一个当前的绿灯, 然后再加一个定时器:ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate( // 在这个定时器,要求没隔一段时间 将当前的灯变红, 并通过 Lamp.blackOut()方法返回下一个灯
new Runnable() // 再将这个返回的灯做 当前 灯, 然后如此循环即可。
{
public void run() //定时器的好处: 相当于一个定时的循环
{
currentLamp=currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
主函数:
主函数中 构造12条路, 因为路和灯都是一一对应的,所以用灯名来给路命名。
命名时可以采用数组的方法,效率高:public static void main(String[] args) {
String[] direction=new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
for(int i=0;i<direction.length;i++)
{
new Road("direction[i]");
}
然后调用灯控制器。
通过这个例子的学习:认为开发项目时,1、思路最重要,要理清思路,将问题模块化。2、使用新技术,提供编程效率。