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

黑马程序员_银行业务调度系统

2013-12-17 00:23 405 查看
------- android培训java培训、期待与您交流! --------------

模拟实现银行业务调度系统逻辑,具体需求如下:

1、银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。

2、有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

3、异步随机生成各种类型的客户,生成各类型用户的概率比例为:

VIP客户 :普通客户 :快速客户 = 1 :6 :3。

4、客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过

程可通过线程Sleep的方式模拟)。

5、各类型客户在其对应窗口按顺序依次办理业务。 

6、当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对

应客户的业务。

7、 随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

8、不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

一、面向对象的分析与设计

有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务 。

首先,经常在银行办理业务的人更有利于理解本系统,每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,要有一个号码管理器对象,让这个对象不断

地产生号码,就等于随机生成了客户。

由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一

由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

各类型客户在其对应窗口按顺序依次办理业务 ,准确地说,应该是窗口依次叫号。

各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

二、类图



三、编写NumberManager类和NumberMachine类

NumberManager类

定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。

定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步。

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

public class NumberManager {
private int lastNumber = 1;
private List<Integer> queueNumber = new ArrayList<Integer>();

public synchronized int generateNumber() {
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchNumber() {
if(queueNumber.size() > 0)
return queueNumber.remove(0);
return null;
}
}


NumberMachine类

定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。

将NumberMachine类设计成单例。

public class NumberMachine {
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;
}

private NumberMachine(){}
public static NumberMachine getInstance() {
return instance;
}
private static NumberMachine instance = new NumberMachine();
}


四、编写ServiceWindow与CustomerType枚举类

CustomerType枚举类

系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。

重写toString方法,返回类型的中文名称。这是在后面编码时重构出来的,刚开始不用考虑。

public enum CustomerType {
COMMON, EXPRESS, VIP;

public String toString() {
switch (this) {
case COMMON:
return "普通";
case EXPRESS:
return "快速";
case VIP:
return name();
}
return null;
}
}


ServiceWindow类

定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。

定义三个方法分别对三种客户进行服务,为了观察运行效果,应详细打印出其中的细节信息。

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

public class SeviceWindow {
private int windowNumber;
private CustomerType type;
public SeviceWindow(int windowNumber, CustomerType type) {
this.windowNumber = windowNumber;
this.type = type;
}
public void start() {
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run() {
while(true) {
switch (type) {
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
});
}

private void commonService() {
System.out.println(windowNumber + "号"+ type + "窗口准备处理普通客户的业务...");
Integer number = NumberMachine.getInstance().getCommonManager().fetchNumber();
if(number != null) {
System.out.println("服务中..." + windowNumber + "号"+ type + "窗口正在为第" + number + "号普通客户服务...");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
int serviseTime = new Random().nextInt(maxRandom) + 1 + Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成..." + windowNumber + "号"+ type + "窗口完成为第" + number + "号普通客户的服务,耗时" + serviseTime/1000 + "秒");
}
else {
System.out.println(windowNumber + "号"+ type + "窗口没有普通客户等待办理业务,空闲一秒钟...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void expressService() {
System.out.println(windowNumber + "号"+ type + "窗口准备处理快速客户的业务...");
Integer number = NumberMachine.getInstance().getExpressManager().fetchNumber();
if(number != null) {
System.out.println("服务中.
4000
.." + windowNumber + "号"+ type + "窗口正在为第" + number + "号快速客户服务...");
int serviseTime = Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成..." + windowNumber + "号"+ type + "窗口完成为第" + number + "号快速客户的服务,耗时" + serviseTime/1000 + "秒");
}
else {
System.out.println(windowNumber + "号"+ type + "窗口没有快速客户等待办理业务,准备处理普通客户的业务...");
commonService();
}
}
private void vipService() {
System.out.println(windowNumber + "号"+ type + "窗口准备处理VIP客户的业务...");
Integer number = NumberMachine.getInstance().getVIPManager().fetchNumber();
if(number != null) {
System.out.println("服务中..." + windowNumber + "号"+ type + "窗口正在为第" + number + "号VIP客户服务...");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
int serviseTime = new Random().nextInt(maxRandom) + 1 + Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviseTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成..." + windowNumber + "号"+ type + "窗口完成为第" + number + "号VIP客户的服务,耗时" + serviseTime/1000 + "秒");
}
else {
System.out.println(windowNumber + "号"+ type + "窗口没有VIP客户等待办理业务,准备处理普通客户的业务...");
commonService();
}
}
}


五、编写MainClass类与Constants类

MainClass类

用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。

接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。

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

public class MainClass {

public static void main(String[] args) {
//定时产生一个普通客户
Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(
new Runnable(){
public void run() {
int number = NumberMachine.getInstance().getCommonManager().generateNumber();
System.out.println("第" + number + "号普通客户正在等待办理业务...");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);
//定时产生一个快速客户
Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(
new Runnable(){
public void run() {
int number = NumberMachine.getInstance().getExpressManager().generateNumber();
System.out.println("第" + number + "号快速客户正在等待办理业务...");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
TimeUnit.SECONDS);
//定时产生一个VIP客户
Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(
new Runnable(){
public void run() {
int number = NumberMachine.getInstance().getVIPManager().generateNumber();
System.out.println("第" + number + "号VIP客户正在等待办理业务...");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS);
/*
* 避免每个窗口刚开始都没有业务可处理,先创建客户再创建窗口
* 新建1-4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口
*/
for (int i = 1; i <= 4; i++) {
new SeviceWindow(i, CustomerType.COMMON).start();
}
new SeviceWindow(5, CustomerType.EXPRESS).start();
new SeviceWindow(6, CustomerType.VIP).start();
}
}
Constants类

定义三个常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME

public class Constants {
public static final int MAX_SERVICE_TIME = 10000;
public static final int MIN_SERVICE_TIME = 1000;
public static final int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}

六、测试运行结果

程序运行一段时间后输出结果如下:

第1号普通客户正在等待办理业务...

第1号VIP客户正在等待办理业务...

第1号快速客户正在等待办理业务...

2号普通窗口准备处理普通客户的业务...

1号普通窗口准备处理普通客户的业务...

服务中...1号普通窗口正在为第1号普通客户服务...

2号普通窗口没有普通客户等待办理业务,空闲一秒钟...

4号普通窗口准备处理普通客户的业务...

4号普通窗口没有普通客户等待办理业务,空闲一秒钟...

3号普通窗口准备处理普通客户的业务...

3号普通窗口没有普通客户等待办理业务,空闲一秒钟...

5号快速窗口准备处理快速客户的业务...

服务中...5号快速窗口正在为第1号快速客户服务...

6号VIP窗口准备处理VIP客户的业务...

服务中...6号VIP窗口正在为第1号VIP客户服务...

第2号普通客户正在等待办理业务...

4号普通窗口准备处理普通客户的业务...

服务中...4号普通窗口正在为第2号普通客户服务...

完成...5号快速窗口完成为第1号快速客户的服务,耗时1秒

5号快速窗口准备处理快速客户的业务...

5号快速窗口没有快速客户等待办理业务,准备处理普通客户的业务...

5号快速窗口准备处理普通客户的业务...

5号快速窗口没有普通客户等待办理业务,空闲一秒钟...

3号普通窗口准备处理普通客户的业务...

3号普通窗口没有普通客户等待办理业务,空闲一秒钟...

2号普通窗口准备处理普通客户的业务...

2号普通窗口没有普通客户等待办理业务,空闲一秒钟...

第3号普通客户正在等待办理业务...

第2号快速客户正在等待办理业务...

3号普通窗口准备处理普通客户的业务...

服务中...3号普通窗口正在为第3号普通客户服务...

2号普通窗口准备处理普通客户的业务...

5号快速窗口准备处理快速客户的业务...

服务中...5号快速窗口正在为第2号快速客户服务...

2号普通窗口没有普通客户等待办理业务,空闲一秒钟...

第4号普通客户正在等待办理业务...

2号普通窗口准备处理普通客户的业务...

服务中...2号普通窗口正在为第4号普通客户服务...

完成...5号快速窗口完成为第2号快速客户的服务,耗时1秒

5号快速窗口准备处理快速客户的业务...

5号快速窗口没有快速客户等待办理业务,准备处理普通客户的业务...

5号快速窗口准备处理普通客户的业务...

5号快速窗口没有普通客户等待办理业务,空闲一秒钟...

第3号快速客户正在等待办理业务...

第5号普通客户正在等待办理业务...

5号快速窗口准备处理快速客户的业务...

服务中...5号快速窗口正在为第3号快速客户服务...

完成...6号VIP窗口完成为第1号VIP客户的服务,耗时4秒

6号VIP窗口准备处理VIP客户的业务...

6号VIP窗口没有VIP客户等待办理业务,准备处理普通客户的业务...

6号VIP窗口准备处理普通客户的业务...

服务中...6号VIP窗口正在为第5号普通客户服务...

第6号普通客户正在等待办理业务...

完成...5号快速窗口完成为第3号快速客户的服务,耗时1秒

5号快速窗口准备处理快速客户的业务...

5号快速窗口没有快速客户等待办理业务,准备处理普通客户的业务...

5号快速窗口准备处理普通客户的业务...

服务中...5号快速窗口正在为第6号普通客户服务...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: