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

黑马程序员——总结:交通灯管理系统

2013-04-05 20:20 330 查看
------- android培训java培训、期待与您交流!
----------

一,要通过分析问题来简化问题:

1、四个方向的车,每个方向都有左转、右转、直行三条线路,但是南与北、东与西是相同情况,所以可以只考虑南方和东方的车的方向,简化了问题。

2、由于左转、直行受到灯的控制,右转是不受灯控制,使问题复杂,所以假设右转也需要看灯,只是设定一个长绿的灯来控制右转,从而统一了思想。

3、由于路线太复杂,容易使人考虑晕。所以先只考虑一个方向的车,做完一个方向再去考虑另一个方向。使思路更清晰。

二,面向对象的设计:

1、需要用到的对象:红绿灯、红绿灯的控制系统、汽车、路线。

2、分析:汽车在什么条件下可以穿过路口?灯变绿,而且前面没有车的时候。

3、车在穿过路口的时候需要问谁?问路,路相当于一个集合,每一个车走的时候都要判断这个集合前面是否还有元素。而且路的对象中也需要提供增加和减少车辆的方法。

4、方法操作的数据在哪个类身上,就把方法定义在哪个类上。

 例:人在黑板上画圆:画圆需要圆心、半径等,都在圆身上,所以画圆方法应该定义在圆上;

 司机刹车:司机只是踩了一下刹车,真正刹车的一系列动作实际是车的内部操作,所以刹车方法应定义在车上;

 售货员统计商品小票价格:价格都是装在了小票上,因此统计价格方法应定义在小票类中;

 人关门,关门的动作需要旋转门、撞到门框、自动锁上门锁,都是门在做,因此关门方法需要定义在门上。

5、由于题目的目的是要体现车辆穿过路口的过程,而不是在描述汽车的移动,所以不必为汽车创建对象,只需要一个字符串表示就可以。

6、工厂模式:两块石头磨成一把石刀,可以砍树,砍成木材,木材做成椅子。

 思路:石头变成石刀以后,石头不存在了;木材变成椅子以后,木材也不存在了,因此我们可以认为是有一个工厂来提供方法生产他们:

StoneKnife sk= KnifeFactory.createKnife(Stone first,Stone second)
Chair chair = ChairFactory.makeChair(Material material);

7、由于一共只有12个灯,不会变,所以使用枚举创建12个交通的对象。

 

三,类的编写:

路类Road:

public class Road{
private List<Stirng> vehicles = new ArrayList<String>();

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

ExcutorService pool = Excutors.newSingleThreadExecutor();
pool.excute(new Runnable(){
public void run(){
for(int i = 1; i<1000; i++){//每隔1-10秒钟,就会在路上出现一辆车
try{
Thread.sleep((new Random().nextInt(10) + 1) * 1000);//设置一个随机值,让线程睡眠1-10秒钟
}catch(InterruptedException e){
e.printStackTrace();
}
vehicle.add(Road.this.name + " " + i);
}
}
});

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//创建调度池对象

timeer.scheduleAtFixedRate(new Runnable(){
public void run(){
if(vehicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){//当为绿灯时,将第一辆车移出。
System.out.println(vechicles.remove(0) + " is traversing !");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
timer.schedule(new Runnable(){},
1,
unit);
}
}

 

灯类Lamp:

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 boolean lighted;//true:绿灯;false:红灯。
private String opposite;//对应的灯
private String next;//下一个灯

private Lamp(String opposite, String next, boolean lighted){ //构造方法,第一个参数为与之一起亮的灯,第二个参数是下一个亮的灯,第三个参数化为当前是红灯还是绿灯。
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}

private Lamp(){

}

public boolean isLighted(){//返回灯是否为绿灯
return lighted;
}

public void light(){//变绿灯
this.lighted = true;
if(opposite != null){//如果不加此判断,则为无限循环此方法,我们只假设南和东的方向有对应的灯,北和西方向没有对应的灯。
Lamp.valueOf(opposite).light();
}
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过");//name()方法是枚举类的方法,可以获得当前枚举对象名字。
}

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;//返回变绿的灯对象。
}

}


灯控制器类LampController

public class LampController{
private Lamp currentLamp;

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

ScheduleExecutorService timer = Executors.newScheduleThreadPool(1);

timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currentLamp = currentLamp.blackOut();
}
},
10,//10秒钟以后
10,//以后每隔10秒钟
TimeUnit.SECONDS);
}
}


主方法测试MainClass:

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(String direction : directions){//创建12个路线类。
new Road(direction);
}

new LampController();

}
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: