这个银行业务调度系统感觉难度还是比较大的,还是要先理清各个模块的关系,画出结构图,才能逐步完成代码,张老师的视频还得抽时间多看几遍。
首先结合实际分析这个银行业务调度系统:一个银行里有 4个普通业务窗口、 1个 VIP业务窗口、 1 个快速窗口、1个取号机。
取号机能打印:普通业务、VIP业务、快速业务 这三种顾客的编号。那么顾客就可以不作分析,在编号类型中体现出来。
设计思路:
1、号码管理模块(NumberManager):生成号码、取走号码
将顾客看作号码,并数组存储,每次从头取走一个。
定义List queueNumbers = new ArrayList(); 知识点:这里new对象时,引用型变量前的类型尽量使用父类,这样更灵活。
private int lastNumber = 0;
生成和取走两个方法:
public synchronized Integer generateNewNumber()
{
queueNumbers.add(++lastNumber);
return lastNumber;
}
public synchronized Integer fetchNumber()
{
if(queueNumbers.size()>0){
return (Integer)queueNumbers.remove(0);
}else{
return null;
}
2、 取号机(NumberMachine)
取号机 只有一个,设计单例模式。
其中包括三个号码管理模块:
private NumberManager commonManager = new NumberManager();
private NumberManager expressManager = new NumberManager();
private NumberManager vipManager = new NumberManager();
接着按单例设计模式:
private NumberMachine(){}
private static NumberMachine instance = new NumberMachine();
public static NumberMachine getInstance(){
return instance;
}
3、服务窗口(ServiceWindow)
要设置窗口的 类型,编号等属性:
private CustomerType type = CustomerType.COMMON;
private int number = 1;
同时提供 设置类型,返回类型 和 返回 编号的方法
public CustomerType getType() {
return type;
}
public void setType(CustomerType type) {
this.type = type;
}
public void setNumber(int number){
this.number = number;
}
一个开始方法
public void start()
{
Executors.newSingleThreadExecutor().execute( //这里又用到jdk1.5之后的新技术。
new Runnable(){
public void run(){
while(true){
switch(type){
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
}
);
}
}
该方法中提供不同的类型窗口不同的服务
private void commonService(){
String windowName = "第" + number + "号" + type + "窗口"; // 开始调用这个窗口
System.out.println(windowName + "开始获取普通任务!");
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber(); // 取号机,获得这个时候的客户
if(serviceNumber != null ){
System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime); // 为客户服务的时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");
}else{
System.out.println(windowName + "没有取到普通任务,正在空闲一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} // 普通窗口
private void expressService(){} //快速窗口
private void vipService(){} //VIP窗口
4、客户类型
这里将客户类型定义成枚举的方法
public enum CustomerType {
COMMON, EXPRESS, VIP;
public String toString(){
String name = null;
switch(this){
case COMMON:
name = "普通";
break;
case EXPRESS:
name = "快速";
break;
case VIP:
name = name();
break;
}
return name;
}
}
5、主函数
主函数是将刚定义的几个类都集合应用起来的。
先生成4个普通窗口
for(int i=1;i<5;i++){
ServiceWindow window = new ServiceWindow();
window.setNumber(i);
window.start();
}
再分别生成 快速 和VIP窗口
//快速窗口
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
//VIP窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
再生成 3 种顾客,也就是在取号机上获得号码
//普通客户拿号 也就是来了一个客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate( //jak1.5新技术,线程定时器,按着给定时间频率循环操作
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS)
// 同理生成 快速客户 和VIP客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
TimeUnit.SECONDS);
//VIP客户生成
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS);
此系统的大致代码和框架就是这些。 设计程序中:中心思想还是要学会面向对象。然后通过对象提供的方法或接口来实现对对象中数据的操作。为了程序的严谨性,要注意成员的修饰。还有些能体现一个人能力的小细节,要通过多看多写才能慢慢掌握和熟练应用。