------- android培训、java培训、期待与您交流! ----------
该视频总共包括了以下部分。
01. 圆了程序员梦却失去了心爱女友漫谈
02. 面试题来源与情景介绍
03. 程序员网校与程序员职业生涯分析
04. 交通灯管理系统的业务和需求分析
05. 精通面向对象的分析和设计的秘诀
06. 交通灯控制系统的类的实现细节分析
07. 编写Road类中模拟汽车上路的代码
08. 定义器与Road类中模拟汽车穿过路口
09. 编写表示交通灯的Lamp类的代码
10. 编写交通灯控制器的类和总成测试
11. 漫谈面试与高薪求职之路
12. 源代码与PPT
张老师给我们进行了详细的分析。首先要明确目的,根据要求进行分析,全部思路明确之后再进行代码的敲写。这样就会变得很简单。
系统要求:
总共有12条路线
String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
/* 解读: 这里使用String类型传递给Road作为构造函数参数,视频里类型的确定有一个步进过程,张老师在讲解之初使用的是Road对象作为参数,之后发现无法使用自身对象作为构造函数参数传递给自己,因为使用构造函数的时候显然对象还没建立,也就是说构造函数里不能使用自身对象作为参数。使用后期改用String类传递名称*/
for(int i=0;i<directions.length;i++){
new Road(directions[i]);
}
/* 解读: 产生Road对象,也就是各个方向的路,本质上是各个方向上的车,功能是*/
new LampController();
/* 解读: 产生整个交通灯系统,功能是*/
Road类
private List<String> vechicles = new ArrayList<String>();
/* 解读: 建立用于存储车辆的集合*/
private String name =null;
/* 解读: 用于想Road类传递路线参数的的临时变量*/
public Road(String name){
/* 解读: Road类的构造函数*/
this.name = name;
//模拟车辆不断随机上路的过程
ExecutorService pool = Executors.newSingleThreadExecutor();
/* 解读: 建立单线程的线程池对象pool,即每次调用Road构造函数都会产生一个ExecutorService,用于在下一步中建立新线程,也就是保证每条线路上的车都对外的隔离,完全是根据自己线路上的红绿灯情况而自动运行*/
pool.execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
/* 解读: 控制当前方向上每次停顿1~10秒再产生下一辆车 */
} catch (InterruptedException e) {
e.printStackTrace();
/* 解读: 当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。*/
}
vechicles.add(Road.this.name + "_" + i);
/* 解读: 为车辆编号,格式为:当前路线 + 序号 */
}
}
});
/* 解读: void execute(Runnable command) 方法是ExecutorServic自Executor接口中继承的方法,用于建立新线程 */
//每隔一秒检查对应的灯是否为绿,是则放行一辆车
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
/* 解读: static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 */
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0) + " is traversing !");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
/* 解读: ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。 这里的设置为1s后开始运行线程,并且每隔1s之后再运行一次。该线程的run方法判断当前路线集合里是否有车,有车的话再判断红绿灯状态是否允许通过,允许通过则把当前路线的车辆集合remove一次*/
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);
/* 解读: 控制路线的灯,因为方向只有12个,是一定的,所以使用了枚举类。构造的第一个参数表示与当前灯同时变绿(也就是通行情况一致)的对应路线,第二个参数表示当前灯变红时下一个变绿的灯, 第三个参数控制灯初始化时是否为绿*/
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
private boolean lighted;
private String opposite;
private String next;
/* 解读: 灯状态参数 */
public boolean isLighted(){
return lighted;
}
/* 解读: 提供给Road线程,用以判断当前路线通行状态的方法 */
public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
}
/* 解读: 仅用于将某个灯变绿,并判断是否有可供点亮的反方向灯,如果有,它对应方向的灯也要变绿。注意这里使用了递归,也是为什么枚举的前两行明明互为opposite,但是第二行对象的opposite参数为null。 */
public Lamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp= null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.light();
}
return nextLamp;
}
/* 解读: 仅用于将某个灯变红,并判断是否有可供关闭的反方向灯,如果有,对应方向的灯也要变红。并且将下一个方向的灯变绿。因为next只是一个表明下一个灯对象名字的String对象,所以专门建立了nextLamp用于点亮下一个方向的灯 */
LampController类
private Lamp currentLamp;
/* 解读: 建立一个临时的灯对象 */
public LampController(){
currentLamp = Lamp.S2N;
currentLamp.light();
/* 解读: 系统初始时让由南向北的灯变绿; */
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
System.out.println("来啊");
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
/* 解读: 每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿,这里使用了和Road类一样的scheduleAtFixedRate定时器,线程建立后10s运行第一次,之后每隔10s运行一次,线程run方法功能为将当前灯状态改为禁止通行,并接收blackOut返回的nextLamp供下一次处理使用 */