首页 > 代码库 > 黑马程序员--关于交通灯管理系统的分析和思考
黑马程序员--关于交通灯管理系统的分析和思考
------- <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)
黑马程序员--关于交通灯管理系统的分析和思考