首页 > 代码库 > 黑马程序员--关于交通灯管理系统的分析和思考

黑马程序员--关于交通灯管理系统的分析和思考

------- <a href=http://www.mamicode.com/"http://www.itheima.com" target="blank">android培训、java培训、期待与您交流! ----------

1. 交通灯管理系统的项目需求

      (1).异步随机生成按照各个路线行驶的车辆

      (2).信号灯忽略黄灯,只考虑红灯和绿灯
      (3).应考虑左转车辆控制信号灯,右转车辆不受信号等控制
    
      (4).具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑
                    注:
                             南北方向车辆与东西方向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆
                       即先走直行,再走拐弯     

  
      (5). 每辆车通过路口时间为1秒(提示:可通过线程sleep的方式模拟)
                          
      (6). 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置
                       
2. 面向对象的分析和设计

   (1). 每条路上都会出现多辆车,路线上要随机正价新的车,在灯绿期间还要每秒钟减少一辆车

             12条线路的选取:选择一个方向,先不考虑其他方向

                        S:                                 
                                        由南向北而去的车辆-------->直行车辆,S2N
                                        由南向西而去的车辆-------->左转车辆,S2W
                                        由南向东而去的车辆-------->右转车辆,S2E
                                        
                        N:
                                        由北向南而去的车辆-------->直行车辆 ,N2S
                                        由北向东而取得车辆-------->左转车辆 ,N2E
                                        由北向西而取得车辆-------->左转车辆 ,N2W
            
                        E:
                                        由东向西而去的车辆-------->直行车辆,E2W
                                        由东向南而去的车辆-------->左转车辆,E2S
                                        由东向北而去的车辆-------->右转车辆,E2N
                                                                                                           
                       W:
                                         由西向东而去的车辆-------->直行车辆,W2E
                                         由西向北而去的车辆-------->左转车辆,W2N
                                         由西向南而去的车辆-------->右转车辆,W2S


                            共有12条线路                                                                                 

       A.      设计一个Road类来表示路线,每个Road对象代表一条路,总共有12条线路,即该系统中要创建12
          个Road实例对象

             一个交通灯管理系统的十字路口的示意图:

                                                       

       B.  每条路上随机增加新的车辆,增加到一个集合中,用集合来保存
       C.  每条路线每隔1秒都会检查控制本路线的等是否为绿灯,是则将本路线中保存车的集合中的第一辆车移除,
                          即表示该车在该条线路的绿灯期间顺利通过
       
   (2). 每条线路每隔一秒钟都会检查控制本条线路的灯是否为绿,一个灯由绿变红时,应该将下一个方向的灯变绿
        D.     设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或(不亮)每个交通灯要有变亮变不亮的方法                                        
           并能返回自己的亮灯状态


        E.      总共有12条线路,所以系统中总共要产生12个交通灯,右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方式
            假设有四个右转的灯,只是这些灯为常亮的状态,即永远不变黑


       F.        除了右拐方向的其他八条路线的灯,它们是两两成对出现的,可以归为4组,因此在编程处理时,只要从这4组中任意取出一个灯
            对这4个灯依次轮流操作变绿或变红,与这4个灯方向对应的灯则随之一同变化,因此Lamp中要有一个变量来记住自己相反方向的灯
           在一个Lamp对象的变亮和变黑的方法中,将对应方向的灯变亮或者变黑,每个灯黑时,都伴随着下一个灯的变亮,Lamp类中海用一
           个变量来记住自己的下一个灯(需要两个相应的变量)
                       
       G.       无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类改用枚举类来做显然具有很大的方便
            性,永远都只有代表12个方向的灯的实例对象

       H.      设计一个LampController类,它定时让当前的绿灯变红                  
                        

  (3). 初步设想会有哪些对象?
                红绿灯,红绿交通灯的控制系统,汽车,路线!
     汽车遇到自己线路上的灯变绿了,就会通过吗?
                 不是的,还要判断其前面是否还有车,此时该如何操作呢?此时应该看路线对象的集合中是否存在车辆,路线的集合中应该封装有
           增加车辆和减少车辆的方法 ,程序需要操作的是车辆穿过路口的过程,即路上减少一辆车辆的过程,所以这个车并不需要单独设计成
          对象,用一个字符串表示即可 

 3.代码实施过程:

              在MyEclipse中创建一个Java Project,名为:Traffic management system,在其目录中创建包cn.itcast.www.TMS.project,在该包的目录下

     分别创建 Road,Lamp,LampController和MainClass类并编写功能代码

  4 .Road类的编写

      (1). 每个Road对象都有一个name成员变量来代表方向,有一个vehicles成员变量来代表方向上的车辆集合。
      (2). 在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)                
      (3).    在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉

Road类代码如下:

    

     

     
5. Lamp类的编写 

          (1).      系统中有12个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,综合这些因素,将Lamp
                类用java5中的枚举形式定义更为简单
                       
          (2).      每个Lamp对象中的亮黑状态用lighted变量表示,选用S2N、S2W、E2W、E2N这四个方向上的Lamp对象依次轮询变亮,
                Lamp对象中还要有一个oppositeLampName变量来表示它们相反方向的灯,再用一个nextLampName变量来表  示此灯变
                亮后的下一个变亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无法再构造方
               法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。
                       
         (3).     增加让Lamp变亮和变黑的方法:light和blackOut,对于S2N、S2W、E2W、E2N这四个方向上的Lamp对象,这两个方法内
               部要让相反方向的灯随之变亮和变黑,blackOut方法还要让下一个灯变亮。
                       
         (4).      除了S2N、S2W、E2W、E2N这四个方向上的Lamp对象之外,其他方向上的Lamp对象的nextLampName和oppositeLampName
             属性设置为null即可,并且S2N、S2W、E2W、E2N这四个方向上的Lamp对象的nextLampName和oppositeLampName属性必须设置
             为null, 以便防止light和blackOut进入死循环 

    Lamp类的代码如下:

       


 6. LampController类的编写

      (1).   整个系统中只能有一套交通灯控制系统,所以,LampController类最好是设计成单例。
      (2).   LampController构造方法中要设定第一个为绿的灯
      (3).   LampController对象的start方法中将当前灯变绿,然后启动一个定时器,每隔10秒将当前灯变红和将下一个灯变绿。

     LampController类的代码如下:

    

    7. MainClass类的编写
        (1).   用for循环创建出代表12条路线的对象
        (2).   接着再获得LampController对象

       MainClass类的代码如下:

     

   运行MainClass的结果为:

              

      
8. 对用面向对象思想编程的一些经验和思考:

      (1).  面向对象设计把握一个重要的经验:
                   即哪个对象拥有数据,该对象就对外提供操作这些数据的方法
      (2).  需要掌握几个典型的面向对象设计的案例
                a. 人在黑板上画圆
                b. 列车司机紧急刹车
                c. 售票员统计收获小票的金额
                d. 把门关上

                e.  小球从一根绳子的一端移动到另一端
                 f. 两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子
       
    (3).分析绳子和小球的面向对象实现过程 :
         小球从一根绳子的一端移动到另一端 ,在这其中有可以定义两个类,绳子Rope和小球Ball,其中小球和绳子到底有什么关系呢?
                     绳子的作用是为小球的移动指明了方向,而小球有滚动的方法 ,小球的下一个点要滚到哪里去,而绳子就提供了nextPoint()的方法 ,绳子就可以根据
              起始坐标 ,结束坐标,此时绳子的构造方法就接收两个点,它也就有一个方法,就是获取某一个点的下一个点 ,小球有移动的方法,而小球是依赖绳子的,

              可以在小球的构造方法中,将绳子传给小球,这样绳子就和小球绑定并产生关系,以此,每次小球运动就会找绳子的方法,每隔一秒钟它就会问绳子下一秒

             的位置在哪儿,绳子具有返回下一个小球运动轨迹的坐标(即数据),所以返回坐标的方法就由绳子来提供,即绳子拥有数据,绳子就对小球(外界)提供

             操作数据的 方法
                           代码描述如下:
           class Rope{
               private Point start;
               private Point end;
               public Rope(Point start,Point end){
                   this.start = start;
                   this.end = end;
               }
               
               public Point nextPoint(Point currentPoint){
                 //若当前点为终止点,则返回null,如果当前点不是线上的点,则抛出异常
               }
           }   
           class Ball{
              private Rope rope;
              private Point currentPoint;
              public Ball(Rope rope,startPoint){
                  this.rope = rope;
                  this.currentPoint =currentPointl;
                }
                
                public void move(){
                    currentPoint = rope.nextPoint(currentPoint);
                    System.out.println("小球移动到了"+currentPoint);
                }

    (4). 用面向对象的思想分析:
                 两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子
                         Stone
                         StoneKnife
                          tree
                         material
                         chair
         两块石头变成一把石刀。,这里肯定有一个外界提供的方法,此方法接受的也是两个参数,才能将两块石头做成石刀 ,则有如下代码:
               StoneKnife = KnifeFactory.createKnife(Stone first,Stone second)
               material = StoneKnife.cut(tree)
               chair = ChairFactory = makeChair(material)                                                                          
          

                                  
                                  
   

黑马程序员--关于交通灯管理系统的分析和思考