-------android培训、java培训、期待与您交流! ----------
交通灯管理系统
面向对象设计思想:
例题:
1, 两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子
用面向对象的思想模拟
如下:
对象有:
石头:Stone
石刀:StoneKnife
木材:Wood
椅子:Chair
两块石头磨成一把刀,则就是一个工厂类,传入两块石头做参数,返回一把石刀
StoneKnifeFactory
木材做成椅子也是一个工厂类,将木材作为参数,返回一把椅子
ChairFactory
代码如下:
StoneKnife
public class StoneKnife { private Stone s1; private Stone s2; // 石刀由两块石头磨成 public StoneKnife(Stone s1, Stone s2) { this.s1 = s1; this.s2 = s2; } // 石刀有砍树的功能 public Wood cutTree() { return new Wood(); } }
public class Chair { // 椅子由木材做成 private Wood w; public Chair(Wood w) { this.w = w; } }StoneKnifeFactory
public class StoneKnifeFactory { public static StoneKnife creatStoneKnife(Stone s1,Stone s2){ return new StoneKnife(s1,s2); } }ChairFactory
public class ChairFactory { public static Chair creatChair(Wood w){ return new Chair(w); } }
public class TestDemo { public static void main(String[] args) { // 创建两块石头 Stone s1 = new Stone(); Stone s2 = new Stone(); // 将两块石头磨成一把石刀 StoneKnife sk = StoneKnifeFactory.creatStoneKnife(s1, s2); // 砍一块木材 Wood w = sk.cutTree(); // 将木材做成椅子 Chair chair = ChairFactory.creatChair(w); } }
2, 球从一根绳子的一端移动到了另一端
两个对象: 球Ball
每个球都应该有一个绳子来指引移动的方向,有一个起始位置,有一个移动的方法,就是从一点到另一点,调用绳子的方法
public class Rope { // 绳子的两个端点,一个代表起点,一个代表终点 private Point start; private Point end; public Rope(Point start, Point end) { this.start = start; this.end = end; } // 从一个点到另一个点 public Point nextPoint(Point point) { // 应根据传进来的点,返回指定的点 return new Point(); } }
绳子 Rope
为球的移动提供方向,两个属性,起始点和终点,有一个方法,获取下一个点
public class Ball { // 为每个球指定一个绳子 private Rope rope; // 每个球都有起始位置 private Point currentPoint; public Ball(Rope rope, Point currentPoint) { this.rope = rope; this.currentPoint = currentPoint; } // 球移动的方法,从绳子一端移动到另一端 public void move() { // 移动到了currentPoint点 currentPoint = rope.nextPoint(currentPoint); System.out.println("小球移动到了" + currentPoint); } }
已知一共有12条路线,右转4条,左转4条,直行4条
右转不受交通灯控制,视为常绿
现在考虑8条路线,因为来往是对称的,所以只用考虑4条路线
分别是
按红,黄,蓝,绿,的顺序
红:SàN直行,该路上绿灯,其它都是红灯
黄:直行结束后,黄:SàW左转,该路上左转灯亮绿灯
蓝:竖着的路行驶结束后,换横着的马路,EàW,
绿:直行结束,再接着该路上左转,EàS
由上可知,4条路线轮流变换红绿灯行驶
交通灯:
使用枚举类,
总共有12条路线,对应的就有12个灯
实际上只需要考虑4个灯轮流交换
交通灯有3个成员变量
一个boolean类型记录自己的状态,是红灯还是绿灯亮
一个String类型变量记录对应方向灯的状态
一个String类型变量记录下一个灯
两个方法,一个是点亮绿灯
一个是绿灯变红灯
//总共12个灯,定义枚举,指定12个Lamp元素即可 public enum Lamp { // 使用String类型变量来封装枚举名,并在初始化中使用,可以避免非法向前引用的问题 S2N("N2S", false, "S2W"), // 1,竖着的马路,向上直行 S2W("N2E", false, "E2W"), // 2,竖着的马路,左转弯 E2W("W2E", false, "E2S"), // 3,横着的马路,直行 E2S("W2N", false, "S2N"), // 4,横着的马路,左转弯 /* 右转路线,灯为常绿 */ S2E(null, true, null), E2N(null, true, null), N2W(null, true, null), W2S( null, true, null), /* 对应方向的灯,不需要进行逻辑考虑,只需遵守上面4个灯的规则就行 */ N2S(null, false, null), N2E(null, false, null), W2E(null, false, null), W2N( null, false, null); // 记录当前状态 private boolean lighted; // 与灯同时为绿的对应方向的灯,保存的是灯的名字,后面可以根据灯的名字获取对应的实例对象 private String opposite; // 灯变红时,下一个变绿的灯 private String next; // 初始化灯,枚举的构造方法必须是私有 private Lamp(String oppsite, boolean lighted, String next) { this.opposite = oppsite; this.lighted = lighted; this.next = next; } // 判断当前灯是否是亮的 public boolean isLighted() { return lighted; } // 当前灯变绿,随之要将对应的灯也变绿 public void light() { this.lighted = true; // 调用自己方法,将对应的灯也变绿,通过灯名获取对应灯的实例对象 if (opposite != null) { Lamp opp = Lamp.valueOf(opposite); opp.light(); System.out.println("当前绿的灯是"+name()+"和"+opposite+"还有右转弯一共6个绿灯"); } } // 当前灯变红,同时返回下一个变绿的灯 public Lamp blackOut() { this.lighted = false; // 将对应方向的灯也变红 if (opposite != null) { Lamp.valueOf(opposite).blackOut(); } // 获得下一个绿灯,并返回 Lamp nextLamp = null; if (next != null) { nextLamp = Lamp.valueOf(next); // 将下一个灯变绿 nextLamp.light(); System.out.println(name()+"和"+opposite+"变红了,"+next+"灯绿了"); } return nextLamp; } }
交通灯的控制器
一个成员变量,用来记录当前的灯
一个方法,定义一个计时器,每过10秒,将当前灯变红,并获取下一个变绿的灯
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(); // 定义一个计时器,每隔指定时间就将当前灯变红,并将下一个灯变绿 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); // 按照指定频率执行线程中的方法中的代码 timer.scheduleAtFixedRate(new Runnable() { // run方法中是指定的要执行的代码 public void run() { // 将当前灯变黑,同时将当前灯指向下一个变绿的灯 currentLamp = currentLamp.blackOut(); } }, 10, 10, TimeUnit.SECONDS); } }
Road类,描述公路
定义一个集合,封装String类型数据,来代表车辆
一共有12条路线,所以每创建一条路线都给该路线指定对应的名字
单独封装一个线程来模拟路上来的车辆,即每条路上随机增加的车辆
再单独封装一个线程来模拟过马路的车辆,即路上减少的车辆
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; public class Road { // 定义集合存储车辆 List<String> vehicles = new ArrayList<String>(); // 每条路都有自己的名字,根据该名字也可以获得该路上对应的灯 private String name; public Road(String name) { this.name = name; // 获得线程池中的一个线程,来向路上添加车辆 ExecutorService pool = Executors.newSingleThreadExecutor(); // new一个Runnable对象,往里面封装添加车辆的代码 pool.execute(new Runnable() { public void run() { for (int i = 1; i <= 1000; i++) { // 每隔1——10秒就添加一辆车辆 try { Thread.sleep((new Random().nextInt(10) + 1) * 1000); } catch (InterruptedException e) { e.printStackTrace(); } vehicles.add(Road.this.name + "_" + i); } } }); // 下面定义方法减少车辆,即车辆穿过路口,也是单独封装到 一个线程中去 // 定义一个线程调度池 ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); // 按固定频率执行线程中的代码,延迟1s执行,之后过1s再执行该代码 timer.scheduleAtFixedRate(new Runnable() { public void run() { // 有车辆才运行 if (vehicles.size() > 0) { // 根据路名获取路灯 Lamp lamp = Lamp.valueOf(Road.this.name); // 如果是绿灯亮 if (lamp.isLighted()) { System.out.println(vehicles.remove(0) + "正在过马路!"); } } } }, 1, 1, TimeUnit.SECONDS); } }
public class MainClass { public static void main(String[] args) { // 将12条路线都创建出来 String[] directors = { "S2N", "S2W", "E2W", "E2S", "S2E", "E2N", "N2W", "W2S", "N2S", "N2E", "W2E", "W2N" }; for (String director : directors) { new Road(director); } new LampController(); } }
当前绿的灯是S2N和N2S还有右转弯一共6个绿灯
S2N_1正在过马路!
S2E_1正在过马路!
W2S_1正在过马路!
S2N_2正在过马路!
N2W_1正在过马路!
S2E_2正在过马路!
E2N_1正在过马路!
E2N_2正在过马路!
W2S_2正在过马路!
N2S_1正在过马路!
当前绿的灯是S2W和N2E还有右转弯一共6个绿灯
S2N和N2S变红了,S2W灯绿了
S2W_1正在过马路!
N2E_1正在过马路!
S2W_2正在过马路!
N2E_2正在过马路!
S2W_3正在过马路!
E2N_3正在过马路!
S2W_4正在过马路!
N2W_2正在过马路!
E2N_4正在过马路!
N2E_3正在过马路!
W2S_3正在过马路!
S2E_3正在过马路!
当前绿的灯是E2W和W2E还有右转弯一共6个绿灯
S2W和N2E变红了,E2W灯绿了
E2W_1正在过马路!
N2W_3正在过马路!
W2E_1正在过马路!
E2W_2正在过马路!
E2N_5正在过马路!
W2E_2正在过马路!
E2W_3正在过马路!
E2W_4正在过马路!
W2S_4正在过马路!
W2E_3正在过马路!
N2W_4正在过马路!
------- android培训、java培训、期待与您交流! ----------