黑马程序员----交通灯管理系统

来源:互联网 发布:温州藤桥网络问政 编辑:程序博客网 时间:2024/05/18 02:26

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

当一个问题摆在我们面前的时候,我们是先通过面向过程去把问题弄清楚,还是直接通过面向对象的方式去解决呢?毫无疑问,我们必须先明白现实当中的问题是如何解决的,然后才是通过计算机语言去实现,而我去了解现实问题时,往往是先一步步的去解决问题,这个时候往往用面向过程的方法分析问题,然后再去抽象各种类,去用面向对象的角度去解决问题。就行张老师讲的先分析清楚问题,然后才去抽象各种类,如果问题没有分析清楚,急于求成的话,往往会把问题弄得一团糟,反而没了头绪。我刚开始看张老师视频的时候,就是对问题分析自己感觉清楚了,然后通过快进的方式看视频,结果到了后面编程,才发现如何解决问题才是最重要的。

总共有12条路线,为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制灯可以假设称为常绿状态,另外,其他的8条线路是两两成对的,可以归为4组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

我们初步设想有红绿灯,红绿灯控制系统,路和车的对象。红绿灯控制系统控制四组灯的亮灭,汽车和灯没有绑定,而是路和灯绑定,每一辆车都在特定的一辆路线上。如果这辆汽车是第一辆则通过,否则要等待路线前面上的车通过,等待它成为第一辆车时才能通过,所以路上必须有增加车和删除车的方法。面向对象是谁拥有数据,谁就应该拥有操作方法。

设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或不亮(红),每个交通灯要有变亮和变黑的方法,并且能返回自己的亮黑状态。因此用枚举类来设计灯这个类。

public enum Lamp {
 //每个枚举类型元素表示灯控制的一个方向
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),
 E2W("W2E","E2S",false),E2S("W2N","S2N",false),
 //由南向东,由东向北,由北向西,由西向南
 S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true),
 //下面元素与上面元素方向相反的灯
 N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false);
 //当前灯是否为绿
 private boolean lighted;
 //相反方向的灯
 private String opposite;
 //下一个变绿的灯
 private String next;
 public boolean isLighted(){
  return this.lighted;
 }
 private Lamp(String opposite,String next,boolean lighted){
  this.lighted=lighted;
  this.opposite=opposite;
  this.next=next;
 }
 //某一个灯变绿,那么它相反方向的灯也要变绿
 public void light(){
  this.lighted=true;
  if(opposite!=null){
   Lamp.valueOf(opposite).light();
  }
  System.out.println(name()+"Lamp is green.下面总共有六个方向会通过汽车");
 }
 /*
  * 当一个灯变红时,它相反方向上的灯也要变红,
  * 并且下一个方向的灯要变绿
  */
 public Lamp backOut(){
  this.lighted=false;
  if(opposite!=null){
   Lamp.valueOf(opposite).backOut();
  }
  Lamp nextLamp=null;
  if(next!=null){
   nextLamp=Lamp.valueOf(next);
   System.out.println("绿灯从"+name()+"切换到下一个"+next);
   nextLamp.light(); 
  }
  return nextLamp;
 }
}

灯的控制系统有一个对象是当前正在亮的灯,还要有一个定时器,控制等的亮灭,如果时间一到要把灯关灭,同时把下一个灯变成当前灯。

public class LampController {
 private Lamp currentLamp;
 public LampController(){
  currentLamp=Lamp.S2N;
  currentLamp.light();
  ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
  /*每隔10秒钟当前绿灯变红,并让下一个方向的灯变绿*/
  timer.scheduleAtFixedRate(new Runnable() { 
   @Override
   public void run() {
    currentLamp=currentLamp.backOut();
   }
  },
  10,
  10,
  TimeUnit.SECONDS );
 } 
}
        每个Road对象都有一个name成员变量来代表方向,有一个vehicles成员变量来代表方向上的车辆集合。在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)。在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。

public class Road {
 private List<String> vechicles = new ArrayList<String>();
 //路的名字
 private String name;
 public Road(String name){
  this.name=name;
     ExecutorService pool=Executors.newSingleThreadExecutor();
  //Thread.sleep(1000)
  pool.execute(new Runnable() {
    @Override
    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();
     }
     vechicles.add(Road.this.name+"_"+i);
     }
    }
   });
  ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(
    new Runnable() {
     @Override
     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"+"剩余车辆数:"+vechicles.size());
         
       }
      } 
     }
    },
    1,
    1,
    TimeUnit.SECONDS);
 }
用for循环创建出代表12条路线的对象。接着再获得LampController对象并调用其start方法。

public static void main(String[] args) {
  System.out.println("----------");
  /*产生12个方向的路线*/
  String[]  roadDirection ={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N",
    "S2E","E2N","N2W","W2S"};
  //
  for(int i=0;i<roadDirection.length;i++){
   new Road(roadDirection[i]);
  }
  //产生整个交通系统
  new LampController();
 }

张老师把车放在了12条路线上,实际上路上的车是存在多个车道,而每个车道上的车并不是通向同一个方向上。其实我们分析问题是都是先把问题抽象简化,然后才具体分析,通过不断的增加条件,然后满足现实需要。实际上我们是有四条通车路线,即南,北,东,西。

----------- android培训、java培训、java学习型技术博客、期待与您交流! -----------

 
原创粉丝点击