交通灯管理系统
一:交通灯管理系统这道题的来源:
有的软件开发公司会把一些他们日后工作的问题拿来考面试者,这样既考查了面试者的能力,又解决了公司的问题,这种面试模式正逐渐扩展。这道交通灯管理系统就是张老师的学生在面试的时候遇到的
二,项目需求:模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1,异步随机生成按照各个路线行驶的车辆。
例如:由南向而来去往北向的车辆----直行车辆
由西向而来去往南向的车辆----右转车辆
有东向而来去往南向的车辆----左转车辆
2,信号灯忽略黄灯,只考虑红灯和绿灯
3,应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4,具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况想的控制逻辑。
5,每辆车通过路口事件为1s(提示:可通过线程sleep的方式模拟)
6,随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7,不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果
三,思路:
1,画图表示路口交通灯(如果遇到不懂,描述又很复杂的问题就画图解决)
2,画图后发现一共有十二条路线,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制灯可以假设称为常绿状态,另外,其他的8条线路是两两成对的,可以归为4组,由此可以简化成只考虑四条线即可。
3,路线的顺序:假设由南开始,南先直行,然后南向左转弯,在东直行,最后再东向南转弯,由此循环
4,确定对象:灯,控制等颜色的控制器,路线。因为汽车减少的方法是路提供的,并且也不需要捕捉车间少的过程,因此车不需要定义对象了,定义在路内部就可以
**********
面向对象深入:
分析面型对象的经验:谁拥有数据,谁就对外提供操作这些数据的方法
案例:1)人在黑板上画圆
对象:Person,Blackboard,circle
方法:draw() //这个方法是黑板类型上的
{
x,y—>radius //此时的圆心和半径都是黑板提供,在黑板上
}
2)售票员统计票据
对象:售票员,票据
动作:统计票据金额—>票据的方法
售票员调用票据对象的getTotalMoney(),然后此方法内部计算票据金额
3)球从绳子的一端移动到另一端
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){}
}
class Ball
{
private Rope rope;
private Point currentPoint;
public Ball(Rope rope,startPoint)
{
this.rope = rope;
this.currentPoint = startPoint;
}
public void move()
{
currentPoint = rope.nextPoitn(currentPoint);
System.out,println(currentPoint);
}
}
4)两块石头磨成一把刀,石头刀砍树砍成木材,木材做成椅子
StoneKnife = KnifeFactory.creatKnife(Stone);
Material = StoneKnife.cut(Tree);
Chair = ChairFactory.makeChait(material);
************
5,设计类:
1)Lamp类表示交通灯(12个)每个灯都有自己的状态,不能随意改变。可以用枚举。又由于对应方向的灯是一致的,可以把两个对应方向的等分为一组,有因为右转的车不受灯的限制,可以视为灯一直是绿的,所以灯一共分为四组就可以了。定义三个成员变量:灯,下一个灯,灯的状态
2)控制器:内部有一个定时器,具有变红的方法,并且返回下个灯
6,程序设计(编码)
//车开到路上的代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
private List<String> vechicles = new ArrayList<String>();
private String name = null;
public Road(String name){
this.name = name;
//假设每一秒就有一辆车,一共1000辆车
ExecutorService pool = Executors.newSingleThreadExecutor();
//Executors执行器,调用线程池,返回一个线程池,
//然后再池中挑选一个线程并执行调用者定义的方法
pool.execute(new Runnable(){
public void run(){
for (int i=1;i<1000;i++){
try {
Thread.sleep((newRandom().nextInt(10)+1)*1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);
//内部类访问外部类成员变量,要加上类名。this
}
}
});
//制作定时器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//Scheduled调度 scheduleAtFixedRate固定频率
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");
//集合中元素调用remove方法的返回值类型是该元素本身类型,如vechicles.remove(0)
}
}
};
}, //任务
1, //过多少事件做这件事
1, //做完后再经过多少时间再做
TimeUnit.SECONDS); //定义时间单位
}
}
//定义灯的类,使用枚举
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();
}
//灯变黑的方法(红色)
public Lamp blackOut(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp= null;
nextLamp = Lamp.valueOf(next);
if(next != null){
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.light();
}
return nextLamp;
}
}
//定义灯的控制器
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
public LampController(){
//定义第一个灯S2N为绿的
currentLamp = Lamp.S2N;
currentLamp.light();
//每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleWithFixedDelay(
new Runnable(){
public void run(){
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
//定义主函数
public class MainClass {
public static void main(String[] args) {
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();//此时开启某一个灯,整个交通灯系统运行
}
}
总结:交通灯管理系统就是基础知识的结合,运用到的知识有线程,枚举,定时器,简单的定义成员函数,构造方法等,还有内部类,着重注意面向对象的分析和深入学习,把对象分析好,方法弄清楚,代码就很好写了。