黑马程序员-笔记-19-交通灯模拟系统

来源:互联网 发布:mac 查看当前路径 编辑:程序博客网 时间:2024/06/05 15:01

-------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

虽然交通灯系统代码上要比银行业务系统简单很多,但是其逻辑我觉得更加复杂,老师的提供的思路非常好,按照我自己的理解,我重写了复写出了交通灯的代码:

/** * 交通灯模拟: 交通系统模拟的是:汽车在道路上行走的过程,车是否能开走,取决于两个方面,一个是路上是否有其他车。另一个是对应道路上的灯。 *  * 所以该系统整体需要三个对象来模拟: 1.车:不需要实例出车,用字符串代替。Car *  * 2.交通灯:交通灯需要有变红变绿的方法。并按照一定的时间间隔交替。Lamp *  * 3.路:路需要提供方法,他需要判断自己当前的路对象上是否有车,并判断当前路面上灯的状态,是否放行车辆。Road *  * 4.交通灯的红绿交替,老师讲课是使用了一个灯控制的类来做,我觉得等自身具备这个方法也可以。LightControl *  * 5.结合实际分析:其实控制路面上车辆行动的交通灯,只有12盏,同理,道路也只有十二条。 * 灯一定是一个枚举模式的,(这么说路也是枚举,为什么没有采取枚举可能是为了方便。无可厚非吧。) *  * 6.交通灯的全分析: 道路上四盏向右转的灯常绿 道路上相对应的两盏灯,状态一致。 道路上交替的灯,状态相反。 * 结合这种情况,一个灯的内部成员,一定有它对应的灯,还有一个和他交替灯。按照这样分析, * 以上前两条分析可以得出,真正交替的等只有四盏,其他的只要修改这四盏灯的内部对应的灯即可进行控制。 *  * 灯本身有一个属性,可以知道其是否可以通过。 *  *  *  * S2N,S2W,E2W,E2S,N2S,N2E,W2E,W2N,S2E,E2N,N2W,W2S; */public class Traffic {public static void main(String[] args) {//开辟十二条路String[] roads ={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"}; for(String name:roads){new Road(name);}LampControl.startControl();}}enum Lamp {// 四盏真正交替的灯(去东e,南s)两个方向为主。S2N("S2W", "N2S", false), S2W("E2W", "N2E", false), E2W("E2S", "W2E", false), E2S("S2W", "W2N", 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);// 当前等对应的下一个灯。灯不能在使用Lamp这个类,这样会导致无法构造。private String next;private String oppsite;// 标志,查看当前等是否是亮点的。private boolean lighted;// 构造函数需要指明以上属性。Lamp(String next, String oppsite, boolean lighted) {this.lighted = lighted;this.oppsite = oppsite;this.next = next;}// 外部需要知道当前等是否点亮的方法。public boolean isLighted() {return lighted;}// 灯提供一个点亮自身的方法public void light() {this.lighted = true;System.out.println(this.name()+"++++++++++++++++++++++++下面将有六个方向上的车经过。++++++++++++++++++++++++");// 只要该灯有对应的灯,那么对应灯应该有相同的状态。if (oppsite != null) {// 如果该等没有对应灯自然没有必要再次去点亮。Lamp.valueOf(oppsite).light();}// 此处不应该再次熄灭交替灯,这样相互调用,就会进入四个灯死循环,四个灯的死循环。}// 灯自身也应具有熄灭自身的方法。同时他熄灭以后,点亮交替等,同时返回下一个刚点亮的等,下一次该这个灯熄灭。public Lamp black() {this.lighted = false;Lamp nextLamp = null;// 一个灯对应的灯也要熄灭。if (oppsite != null) {Lamp.valueOf(oppsite).black();}// 点亮交替等if (next != null) {nextLamp = Lamp.valueOf(next);nextLamp.light();}return nextLamp;}}// 控制等交替明暗的类。class LampControl {static Lamp lamp = Lamp.S2N;public static void startControl(){//控制器启动时,要提前开启一盏在交替中的灯。//final Lamp lamp = Lamp.S2N;//我自己写这个内部灯将他放在了成员变量的位置,这个是不可以的。final修饰后不可以修改了。lamp.light();//使用定时任务,每十秒进行一次交替。Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {//熄灭当前灯后,要返回下一个等待熄灭的灯。这样整个交通灯交替就形成了。lamp = lamp.black();}}, 10,10,TimeUnit.SECONDS);}}//Road类,用于车辆的运行判断。class Road{private String name;//List<Integer> queue = new ArrayList<Integer>();List<String> queue = new ArrayList<String>();public Road(String name){this.name = name;//需要模拟车子逐渐上路,准备过去。Executors.newSingleThreadExecutor().execute(new Runnable() {@Overridepublic void run() {//模拟一千两车准备过当前路。车来的速度在十秒左右一辆。for(int i=1;i<1001;i++){queue.add(Road.this.name+"_"+i);//System.out.println(Road.this.name+"路上,第"+i+"号车辆,进如队列。");try {Thread.sleep((new Random().nextInt(10)+1)*100);} catch (InterruptedException e) {e.printStackTrace();}}}});//启动定时任务,每一秒扫描一次路上是否可以通过车辆,是否有车,灯是否为绿。Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {if(queue.size()>0){boolean lighted = Lamp.valueOf(Road.this.name).isLighted();if(lighted){System.out.println(Road.this.name+"路上,第" +queue.remove(0)+"号车通过!!!" );}}}}, 1, 1, TimeUnit.SECONDS);}}


原创粉丝点击