您的位置:首页 > 职场人生

黑马程序员--银行业务调度系统学习

2013-06-27 12:48 495 查看
本例学习总结:本案例中用到了单例设计模式,要明白客户号与窗口叫号的产生方法,明白其中的逻辑关系。面向对象方法的运用,比如,窗口有类型属性是普通还是快速还是vip,有号这个属性,窗口是几号窗口,针对不同窗口再设计该窗口的处理方法,这样逻辑就清楚了。

需求分析:1.银行有三种业务窗口,分别为普通,快速,vip窗口,分别班里对应客户的业务,但是,快速和vip窗口可以办理普通客户业务。2,有三种类型客户,普通,快速,vip客户。3,模拟客户出现的概率比为6:3:1。4,普通和vip客户办理业务时间用随机数表示,快速客户业务办理时间用最小时间表示。

设计实现:三种类型客户办理业务时要有客户号,需要生成三种客户号,三种类型客户号有一个出客户号机器产生,所以,先设计一个产生客户号的类

import java.util.ArrayList;
import java.util.List;

public class NumberManager {
private int lastNumber = 1;
//为了取出排队号码方便,采用ArrayList
private List<Integer> queueNumber = new ArrayList<Integer>();
//由于取出和产生号码共享数据,要考虑同步问题,如果函数返回类型为int,由于在判断取出的号码是否为空,返回null时会出错,
//所以用Integer作为返回类型,使用java的自动装箱特性
public synchronized Integer generateNewNumber() {
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchNumber() {
if (queueNumber.size() > 0) {
return queueNumber.remove(0);
}
else {
return null;
}
}
}

然后,对于三种类型客户,设计一个类,管理产生的客户号如下:

public class NumberMachine {
/*
* 单例设计模式
*/
private NumberMachine(){}
private static NumberMachine instance = new NumberMachine();
public static NumberMachine getInstance() {
return instance;
}

private NumberManager commonManager = new NumberManager();
private NumberManager expressManager = new NumberManager();
private NumberManager vipManager = new NumberManager();

public NumberManager getCommonManager() {
return commonManager;
}
public NumberManager getExpressManager() {
return expressManager;
}
public NumberManager getVipManager() {
return vipManager;
}

}

用到了单例设计模式,这是考虑到三种类型客户号有一个客户号机产生。

然后设计办理客户业务的窗口类,有属性:窗口类型和窗口号,在start方法中完成业务办理,分三种类型处理

import java.util.Random;
import java.util.concurrent.Executors;

public class ServiceWindow {

private int number = 1;
private CustomerType type = CustomerType.COMMON;

public void setNumber(int number) {
this.number = number;
}
public void setType(CustomerType type) {
this.type = type;
}
public CustomerType getType() {
return type;
}

public void start() {
Executors.newSingleThreadExecutor().execute(new Runnable() {

@Override
public void run() {
while (true) {
switch (type) {
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;

}
}
}
});
}

以普通业务办理为例:下面是commonService()方法的代码:

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 maxRand = Constants.MAX_SEVICE_TIME - Constants.MIN_SEVICE_TIME;
int serviceTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SEVICE_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();
}
}
}

最后完成测试用例类:

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class Main{

public static void main(String[] args) {
//产生4个普通窗口
for(int i=1;i<5;i++){
ServiceWindow window =  new ServiceWindow();
window.setNumber(i);
window.start();
}

//产生1个快速窗口
ServiceWindow expressWindow =  new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();

//产生1个VIP窗口
ServiceWindow vipWindow =  new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();

//普通客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);

//快速客户拿号
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);
}

}


其中COMMON_CUSTOMER_INTERVAL_TIME值是1,表明一个普通客户在一秒后出现一个,所以快速客户和vip客户出现的时间就是COMMON_CUSTOMER_INTERVAL_TIME*2和COMMON_CUSTOMER_INTERVAL_TIME*6.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: