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

来源:互联网 发布:广联达计量软件 编辑:程序博客网 时间:2024/05/21 22:37

------- 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();}}

 

原创粉丝点击