黑马程序员--7K项目--实现简单的交通灯管理系统

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

目录:

1.项目需求      2.浅析OOP    3.需求分析      4.代码实现五.项目总结


1.项目需求:

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:

Ø 异步随机生成按照各个路线行驶的车辆。

例如:

       由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。

Ø 信号灯忽略黄灯,只考虑红灯和绿灯。

Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


 

2.浅析OOP:

面向对象谈起来较为空泛,他有三大特征:封装、继承、多态,

兹以为这不是他的思想,而是他的体现形式。何为面向对象呢?

如:两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子。

请用面向对象的思想来解释如上陈述。

首先进行名词提炼:石头、石刀、树、木材、椅子

石头:Stone

石刀:StoneKnife

树Tree

木材:TreeMaterial
椅子:Chair

然后考虑谁拥有数据,谁方可操作:

1.石刀源于石头打磨而出:KnifeFactory.createKnife(Stone stone1, Stone stone2);

2.木材由树被砍而来:TreeMaterial treeMaterial = StoneKnife.cut(Tree   tree);

3.椅子由木材加工而成:ChairFactory.makeChair(TreeMaterial   treeMaterial)

如上:OOP其实就是将复杂的问题抽象化,更多的利用人的主观思维来思考,从而不用追寻着过程来实现每一个细节,降低了

功能之间的耦合性,使对象本身具有高内聚的特点,相对于模块化程序设计,面向对象的设计思想更有利于程序设计,

也更符合我们的思考方式。

由于水平所限,暂时只能想到这种层面。


3.需求分析:

通过浅析OOP,我们来使用此思想来对这个项目需求进行分析,抽象化的同时采用至顶而下的设计方式。

思路:

1.名词提炼:道路Road、车辆Car、交通灯Lamp、道路交通灯控制器LampController

2.谁拥有数据,谁方可操作:

     每个十字路口由一套控制器LampController来控制各个道路的交通灯Lamp转换,各个道路Road来控制他们本身路线的车辆Car.

    (1).道路Road本身容纳车辆Car,可以将道路视为容器,容纳异步随机生成的Car,由于此项目中Car没有其他用处,

               故使用字符串替代。Road还要提供操作生成车辆和车辆通过的两种方法。

               每个十字路口有12条路线,对应的我们设置12个交通指示灯。

    (2).交通灯Lamp本身有两种状态:红和绿,所以交通灯本身要提供这两种方法,而且固定为12个路线指示灯,考虑枚举。

    (3).道路交通控制器LampController:对整个交通进行控制,定时切换不同路线的Lamp状态。


4.代码实现:

1.Lamp类的实现:

package cn.itcast.trafficmanage;  
  
/** 
 * 每个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);  
      
    private Lamp(String opposite,String next,boolean lighted){  
        this.opposite = opposite;  
        this.next = next;  
        this.lighted = lighted;  
    }  
  
  
    /*当前灯是否为绿*/   
    private boolean lighted;  
    /*与当前灯同时为绿的对应方向*/     
    private String opposite;  
    /*当前灯变红时下一个变绿的灯*/     
    private String next;  
    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() + "-------->切换为" + next);            
            nextLamp.light();  
        }  
        return nextLamp;  
    }  
} 


 

2.Road类:

package cn.itcast.trafficmanage;  
  
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 {  
                        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(){  
                    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,  
                TimeUnit.SECONDS);  
          
    }  
} 


 

3.LampController类:

package cn.itcast.trafficmanage;  
  
import java.util.concurrent.Executors;  
import java.util.concurrent.ScheduledExecutorService;  
import java.util.concurrent.TimeUnit;  
  
public class LampController {  
    private Lamp currentLamp;  
      
    public LampController(){  
        //刚开始让由南向北的灯变绿;        
        currentLamp = Lamp.S2N;  
        currentLamp.light();  
          
        /*每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿*/        
        ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);  
        timer.scheduleAtFixedRate(  
                new Runnable(){  
                    public  void run(){  
                        System.out.println("来啊");  
                        currentLamp = currentLamp.blackOut();  
                }  
                },  
                10,  
                10,  
                TimeUnit.SECONDS);  
    }  
} 

 

4.程序执行类:MainClass

package cn.itcast.trafficmanage;  
  
public class MainClass {  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
          
        /*产生12个方向的路线*/        
        String [] directions = new String[]{  
                "S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"       
        };  
        for(int i=0;i<directions.length;i++){  
            new Road(directions[i]);  
        }  
          
        /*产生整个交通灯系统*/         
        new LampController();  
    }  
  
}


 

5.项目总结:

     1.最重要的是要熟悉并掌握面向对象编程思想,以现实为模板进行思考。

     2.自顶向下进行设计,将方法与数据归属到相应的类中进行实现。

     3.在具体实现过程中,有很多知识点不是很熟悉,如Executors类如何进行线程管理控制,

         内部类在局部中使用时变量应注意哪些问题等等,有待加强。

     4.考虑问题的严谨性,如交通灯的构造函数中,就需要传递三个变量,next,oppsite,lighted,

        而且相对路线的lamp之间注意什么,车辆右转弯为什么长时为绿。

         Road中是如何进行异步生成车辆及车辆移出的等等。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值