黑马程序员--交通灯管理系统的心得…

交通灯管理系统的心得与体会 - 蓦然回首*小强 - 蓦然回首*小强

 --------android培训java培训期待与您交流------

需求分析:上图是一个双向车道十字路口交通示意图;分四个方位,各依方向行驶;不妨我们就处在S这个路口,前面有信号灯,左侧是

向左转弯(NL),中间是直行(NM),右边绿灯是右转(NR),这个命名规范是,北方:N,有三个灯,左边的L,中间的为M(middle),右边的为R,因此北方的三个灯依次表示为:NL,NM,NR,西侧的:WL,WM,WR,南侧的为:SL,SM,SR,东侧的:EL,EM,ER;

我们知道交通信号灯的变幻次序为:假设我们现在在s这个位置,那么如果NM为绿灯,NM的下一个为NL,相对的那个灯为SM,所谓的相对的灯就是说,变化情况和本灯保持一致。因此我们可以标出整个信号灯的变化情况:假设从NM为绿开始数;

NM--->NL--->WM-->WL-->SM-->SL-->EM-->EL,由于右转弯永远是绿灯,因此可不做考虑;

对象的设计:

这里共出现了这么几个对象:交通灯(十二个方向的灯),车,以及控制交通灯的变化的控制器,因为我们知道

车是根据信号灯来走的,而信号灯是有控制器控制的;

进一步分析我们知道,这个车也是根据方向来的,有十二个方向的车在行驶,我们可以这样想,做出一个集合存放车,这个车是有方向的的,每一个方向有好多车,因此我们可以设计设计出一个线路类:并创建出十二个对象:每个对象代表一个方位,存放一些车;同时为了模拟现实情况,可以随机的产生一些车,存入线路这个集合中;同时车在不断的产生,即不断的开来,又不断的开走;代码如下:


public class Road {
 //定义一个集合用于存放车辆;存的值是某个方向上的第 辆车;
 private List<String> vehicles = new ArrayList<String>();
 private String name;//这是车的线路名称;
 public Road(String name) {
  this.name = name;
  ExecutorService pool = Executors.newSingleThreadExecutor();
//启动一个单线程的线程 ,用来模拟车开了,为了代表随意性,用随机数来表示经过的时间;
  pool.execute(new Runnable() {
   @Override
   public void run() {
    for (int i = 1; i != 1000; i++) {
     try {
      Thread.sleep((new Random().nextInt(10) + 1) * 1000);
     } catch (InterruptedException e) {
      throw new RuntimeException(e);
     }
     vehicles.add(Road.this.name + "" + i);
//用线路名和该线路车的编号组合表示一辆车,比如NR2,表示S方位向右转的第二辆车
    }
   }
  });
  ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//启动一个定时器来模拟车的走去;和信号灯的变化;
  timer.scheduleAtFixedRate(new Runnable() {
   @Override
   public void run() {
    if (vehicles.size() > 0) {
//判断灯是否允许行车;
     if (TrafficLamp.valueOf(Road.this.name).isLigthed()) {
      System.out.println(vehicles.remove(0)
        + "is passing the road");
     }
    }
   }
  }, 1, 1, TimeUnit.SECONDS);//表示每间隔一秒就有一辆车开走;
 }
 public Road() {
 }
}
 

线路和车的关系描述好了我们就该来描述信号灯了,经过之前的分析,只要描述好了一个方向上的车,其他方向的车可以以此类推,因此某个方向的灯上应该有这些消息:1 自己这个灯是红还是绿。 2 那个灯和我是相对的,即如果我变了,就通知这个相对的灯也变化;

3 我的灯的下一个灯是那个,即我这个灯要变化了,我要切换到下一个灯去,做下一轮的切换;那么这个灯他应该有哪些相应的方法和属性呢?

1 属性:相对的灯和下一个灯,以及本灯的状态;

2 方法:判断这个灯是红还是绿

3 灯的切换,由红变绿,由绿变红;

因此代码如下:

 

public enum TrafficLamp {
 NM(false, "SM", "NL"), NL(false, "SL", "WM"), WM(false, "EM", "WL"), WL(
   false, "EL", "SM"), SM(false, "NM", "SL"), SL(false, "NL", "EM"), EM(
   false, "WM", "EL"), EL(false, "WL", "NM"), NR(true), WR(true), SR(
   true), ER(true);//注意第一个参数表示这个灯的初始状态,第二个参数表示相对的灯,第三个参数表示,下一个灯;
//必须注意的是,这个灯的切换顺序要按照起初的分析的情况依次排序;
 private boolean lighted;
 private String next;
 private String opposite;

 

 private TrafficLamp() {
 }

 private TrafficLamp(boolean lighted) {
  this.lighted = lighted;
 }

 private TrafficLamp(boolean lighted, String opposite, String next) {
  this.lighted = lighted;
  this.opposite = opposite;
  this.next = next;
 }

 public boolean isLigthed() {
  return lighted;
 }

 public void light() {
  this.lighted = true;

  if (opposite != null) {
   TrafficLamp.valueOf(opposite).lighted = true;

//由于涉及到变量声明的先后问题,我们采用字符串的方式存入枚举,然后通过枚举的方法取出;
  }
  System.out.println(this + "变绿了");
 }

 public TrafficLamp blackOut() {
  this.lighted = false;
  if (opposite != null) {
   TrafficLamp.valueOf(opposite).lighted = false;
   
  }
  TrafficLamp nextLamp = TrafficLamp.valueOf(next);
  if (next != null) {
   nextLamp.light();
   System.out.println(this+"切换为"+next);
  }
  System.out.println(this + "变红了");
  return nextLamp;
 }
}

交通灯控制器:完成的功能有:做各灯的切换工作,我们做出一个定时器,每隔十秒灯切换一次;
在初始化时我们就给这些灯状态做出指定;
代 如下:public class TrafficLampController {
 private TrafficLamp currentTrafficLamp;
// 识当前灯的状态,由于这些灯形成了一个链条,通过相对灯和下一个灯,做着这些灯的循环切换;

 

 public TrafficLampController() {
  currentTrafficLamp = TrafficLamp.NM;
  currentTrafficLamp.light();//第一个灯是绿灯;这个动作同时指定了相对灯的状态;
  ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(new Runnable() {

   @Override
   public void run() {
    currentTrafficLamp=currentTrafficLamp.blackOut();//这个灯过10秒切换了,切换时指定下一个灯为绿灯,进行下一轮的切换;
   }
  },
  10,
  10,
  TimeUnit.SECONDS);
 }
}
测试类:

 


public static void main(String[] args) {
  String[] roadLines = new String[] { "NM", "NL", "WM", "WL", "SM", "SL",
    "EM", "EL", "NR", "WR", "SR", "ER" };
  for (int i = 0; i < roadLines.length; i++) {
   new Road(roadLines[i]);
  }
  new TrafficLampController();
 }
测试结果;
交通灯管理系统的心得与体会 - 蓦然回首*小强 - 蓦然回首*小强
 
结果分析:显示南北向直行---》然后是南北向的左转弯---》》然后是东西向的直行。。。。
以此类推。
对使用的的 个并发库进行简单的介绍:
CopyOnWriteArrayList:线程并发安全的集合,是List的实现子类;跟List使用差不多,更 安全;
ExecutorService threadPool = Executors.newFixedThreadPool(1);//线程 ,产生固定数量的线程的线程 ;
ScheduledExecutorService scheduledExecutorService = Executors
    .newScheduledThreadPool(1);//产生线程调度的线程 ;
scheduleAtFixedRate方法可以实现定时器功能,即隔多长时间产生执行一个任务;
总结分析:刚开始,想不到用JDK1.5里面的线程并发库去解决,程序的模型也设计的不是很好,经过老师的点拨,思路慢慢开阔了。
其实这只是一种思想,有了这种分析问题的思路,代 其实是不难的,难的是不知道用什么技术区解决,其实这些技术我们都知道,只是一下子想不到,我想是由于做的太少吧,慢慢的就熟悉了。
补充:需要好好的看看JDK1.5并发库中的API文档。


<script type="text/javascript" id="wumiiRelatedItems"> </script>
 
阅读(11) | 评论(0)
推荐 转载
历史上的今天
最近读者
热度
在LOFTER的更多文章
评论
\&quot;交通灯管理系统的心得与体会
\r\n

 --------android培训java培训期待与您交流------

\r\n

需求分析:上图是一个双向车道十字路口交通示意图;分四个方位,各依方向行驶;不妨我们就处在S这个路口,前面有信号灯,左侧是

\r\n

向左转弯(NL),中间是直行(NM),右边绿灯是右转(NR),这个命名规范是,北方:N,有三个灯,左边的L,中间的为M(middle),右边的为R,因此北方的三个灯依次表示为:NL,NM,NR,西侧的:WL,WM,WR,南侧的为:SL,SM,SR,东侧的:EL,EM,ER;

\r\n

我们知道交通信号灯的变幻次序为:假设我们现在在s这个位置,那么如果NM为绿灯,NM的下一个为NL,相对的那个灯为SM,所谓的相对的灯就是说,变化情况和本灯保持一致。因此我们可以标出整个信号灯的变化情况:假设从NM为绿开始数;

\r\n

NM--->NL---

', blogTag:'jdk1.5线程并发库', blogUrl:'blog/static/217276209201331875244452 ', isPublished:1, istop:false, type:0, modifyTime:1400160374597, publishTime:1366291651256, permalink:'blog/static/217276209201331875244452 ', commentCount:0, mainCommentCount:0, recommendCount:0, bsrk:-100, publisherId:0, recomBlogHome:false, currentRecomBlog:false, attachmentsFileIds:[], vote:{}, groupInfo:{}, friendstatus:'none', followstatus:'unFollow', pubSucc:'', visitorProvince:'', visitorCity:'', visitorNewUser:false, postAddInfo:{}, mset:'000', mcon:'', srk:-100, remindgoodnightblog:false, isBlackVisitor:false, isShowYodaoAd:false, hostIntro:'JAVA软件工程师,有扎实的Java基础,熟悉JavaEE技术,对框架的底层原理熟悉,学习能力强。', hmcon:'0', selfRecomBlogCount:'0', lofter_single:'' }
{if x.visitorName==visitor.userName} ${x.visitorNickname|escape} {else} ${x.visitorNickname|escape} {/if}
{if x.moveFrom=='wap'}   {elseif x.moveFrom=='iphone'}   {elseif x.moveFrom=='android'}   {elseif x.moveFrom=='mobile'}   {/if} ${fn(x.visitorNickname,8)|escape}
{/if} {/list}
${a.selfIntro|escape}{if great260}${suplement}{/if}
 
{/if}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值