Java交通灯项目一点感悟
1.编程规范 不要在面试时再去注意编程规范的问题,而要在平时练习的细节中就要注意到这一点,按照规范去编程,养成好的习惯。 A:建立包名 在开发中一般用公司的域名的反写作为包名的,例如www.baidu.com,那么包名就为com.baidu,然后再加上开发的项目名等,还有包名为全部小写。 B:定义变量 注意定义变量的用名规范,变量名要做到见名知意,而且如果有多个词汇组成,那么首单词全部小写,第二个单词首字母大写。 2.编程建议 在平时创建对象时一般都直接用类名直接创建对象,然而听张老师的视频的建议是面向接口编程。 A:面向接口编程,多态的前提之一。 B:接口是一组规范,它规定了实现接口的类或接口必须实现拥有的一组规则。 C:面向接口编程可以提高程序的可扩展性。 3.交通项目知识点分析 在我们平时可能并不注意这些现象,所以编写这个程序的前提是要理解现实生活的一些现象,在十字路口,同一个方向的灯是一致的,假如说南面的交通灯是绿的,那么背面的灯也是绿的,在此时南北方向的车都可以通行,由南往西转弯的车和由北往东转弯的车,当然右转的车俩不受交通灯的控制,所以把车辆分类为:
在这里同一中颜色的为可以在直行车辆行驶完后然后再行驶,通俗的说就是属于同一个系列的。 4.项目分析 根据交通灯项目分析定义为四个类,一个是road类,Lamp类,LampController类和MainClass测试类。 A:Road类 结合生活常识,车辆行驶的方向上分类有12个方向,那么对应到Road类上相当于有12条路可以供这些车来行驶,所以创建了12条Road类实例对象。 在每条路上随机产生车辆,然后把这些产生的车辆存储到集合中。 然后检查相应路线上的灯是否是绿灯,如果是,那么车辆放行,并在集合中相应去除这些车辆。 package com.isoftstone.interview.traffic; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 每个Road对象代表一条路线,总共有12条路线,即系统中总共要产生12个Road实例对象。 * 每条路线上随机增加新的车辆,增加到一个集合中保存。 * 每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。 * */ public class Road { /** * 定义集合存储随机出现的车辆 */ private List<String> vechicles = new ArrayList<String>(); /** * 定义路线名称变量 */ private String name =null; public Road(String name){ this.name = name; //模拟车辆不断随机上路的过程,用一个单独的线程专门产生车辆 ExecutorService pool = Executors.newSingleThreadExecutor(); pool.execute(new Runnable(){ public void run(){ for(int i=1;i<1000;i++){ try { //1~10秒内随机产生一辆车 Thread.sleep((new Random().nextInt(10) + 1) * 1000); } catch (InterruptedException e) { e.printStackTrace(); } //车辆进入线程,名称为name_i vechicles.add(Road.this.name + "_" + i); } } }); //定义一个定时器,每隔一秒检查对应的灯是否为绿,是则放行一辆车 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); 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,//每个1秒执行一次 TimeUnit.SECONDS); } }
B:Lamp类 Lamp类表示交通灯,那么有12个方向就对应有12个交通灯,除了右转的灯外别的8个方向上的灯都是成对出现的,那么就可以把这些灯非为4组,让这个组中的一个灯来控制相应的灯,然而也记住下一个灯的变化。 在这里用枚举可以简化了编程的复杂程度。 所以,相反方向和下一个方向的灯用字符串形式表示。
package com.isoftstone.interview.traffic; /** * 每个Lamp元素代表一个方向上的灯,总共有12个方向,所有总共有12个Lamp元素。 * 有如下一些方向上的灯,每两个形成一组,一组灯同时变绿或变红,所以, * 程序代码只需要控制每组灯中的一个灯即可: * s2n,n2s * s2w,n2e * e2w,w2e * e2s,w2n * s2e,n2w * e2n,w2s * 上面最后两行的灯是虚拟的,由于从南向东和从西向北、以及它们的对应方向不受红绿灯的控制, * 所以,可以假想它们总是绿灯。 * */ 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); /** * lighted为灯的状态 */ private boolean lighted; /** * 与当前灯同时为绿的对应方向的灯 */ private String opposite; /** * 当前灯变红时下一个变绿的灯 */ private String next; //构造函数 private Lamp(String opposite,String next,boolean lighted){ this.opposite = opposite; this.next = next; this.lighted = lighted; } 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个方向能看到汽车穿过!"); } /** * 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿 * @return 下一个要变绿的灯 */ 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() + " <a href="ASP.Net+Android+IOS‘>http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href=".Net‘>http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------