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

黑马程序员:银行业务调度系统分析及代码实现

2013-11-21 12:45 381 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------银行业务调度系统

对象分析:

1.客户

2.服务窗口

3.号码机器

对象上的属性和方法分析:

客户

客户类型:普通客户、快速客户、VIP客户

需要用到枚举:因为客户类型是固定的三类客户

服务窗口

窗口类型:普通窗口、快速窗口、VIP窗口

功能:

1.提供设置窗口号、窗口类型的方法

2.获取号码并处理客户业务

需要用到多线程:因为是多个窗口同时工作的

号码机器

号码:普通号码、快速号码、VIP号码

功能:产生号码提供给客户、将产生的最前面的号码提供给窗口

需要用到同步:因为两个方法是不同线程操作,当多个线程操作同一个数据的时候会出现问题,所以要让他们互斥。

需要用到单例:因为号码机器只有一台

CustomerType:客户类型

/*
* 因为客户类型是固定的三种类型,所以使用枚举
* 判断当前枚举类型,并覆盖toString方法,根据枚举类型指定对应的客户类型name
*/
package cn.itcast.Mr_Zhang.BankQueue;

public enum CustomerType {
COMMON,EXPRESS,VIP;

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


ServiceWindows:服务窗口

/*
* 服务窗口共有三类:普通,快速,VIP
* 1.若快速、VIP窗口没有未用户办理业务的时候,需要为普通客户办理业务
* 2.VIP客户:普通客户:快速客户 = 1:6:3
* 思路:
* 1.窗口应该有对应的窗口ID、窗口名称、窗口类型
* 2.根据客户类型选择对应窗口的业务执行方法
* 3.窗口需要有工作的方法:即取号,并以Sleep代替办理业务的时间
* 4.当快速和VIP窗口没有对应的快速和VIP客户时,需调用普通窗口的方法为普通客户服务
*/
package cn.itcast.Mr_Zhang.BankQueue;

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

public class ServiceWindows {
/*初始化窗口号及客户类型并提供外部设置的方法*/
private int windowId = 1;
private CustomerType type = CustomerType.COMMON;

public void setWindowId(int windowId) {
this.windowId = windowId;
}

public void setType(CustomerType type) {
this.type = type;
}

/*定义窗口启动方法,根据不同客户类型启动不同窗口
*这里要注意:若start中没用定义新线程来执行方法,那么在main方法中创建多个窗口的时候,第一个窗口被启动时就会一直循环。
*这里是完成整个项目犯错的地方,特别要注意
*/
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run(){
switch(type){
case COMMON :
/*因为窗口启动之后需要一直处理该类型的客户,所以要一直使用该窗口的方法*/
while(true)
commonWindow();
case EXPRESS :
while(true)
expressWindow();
case VIP :
while(true)
vipWindow();
}
}
});

}

/*普通窗口*/
private void commonWindow() {
String windowName = "第" + windowId + "号" + type + "窗口";
Integer number = NumberMechine.getNumberMechine().getCommonNumber().fetchNumber();
System.out.println(windowName + "正在获取任务");
if (number != null)
try {
int maxRondom = Constants.SERVICE_TIME_MAX - Constants.SERVICE_TIME_MIN;
int serviceTime = new Random().nextInt(maxRondom) + 1 + Constants.SERVICE_TIME_MIN;
Thread.sleep(serviceTime);
System.out.println(windowName + "为第" + number + "号" + "普通客户服务,耗时:" + serviceTime/1000 + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
else
System.out.println(windowName + "没有获取到任务,等待一秒钟");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}

/*快速窗口*/
private void expressWindow() {
String windowName = "第" + windowId + "号" + type + "窗口";
Integer number = NumberMechine.getNumberMechine().getExpressNumber().fetchNumber();
if (number != null)
try {
int serviceTime = Constants.SERVICE_TIME_MIN;
Thread.sleep(serviceTime);
System.out.println(windowName + "为第" + number + "号" + "快速客户服务,耗时:" + serviceTime/1000 + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
else
System.out.println(windowName + "未获取到任务,进入普通任务获取阶段");
commonWindow();
}

/*VIP窗口*/
private void vipWindow() {
String windowName = "第" + windowId + "号" + type + "窗口";
Integer number = NumberMechine.getNumberMechine().getVipNumber().fetchNumber();
if (number != null)
try {
int maxRondom = Constants.SERVICE_TIME_MAX - Constants.SERVICE_TIME_MIN;
int serviceTime = new Random().nextInt(maxRondom) + 1 + Constants.SERVICE_TIME_MIN;
Thread.sleep(serviceTime);
System.out.println(windowName + "为第" + number + "号" + "VIP客户服务,耗时:" + serviceTime/1000 + "秒");
} catch (InterruptedException e) {
e.printStackTrace();
}
else
System.out.println(windowName + "未获取到任务,进入普通任务获取阶段");
/*若VIP窗口未取得VIP号码管理中的号码,则为普通客户服务*/
commonWindow();
}
}


NumberManager:号码管理器

/*
* 号码管理器的功能:
* 用户取号:产生号码
* 窗口取号:取得已产生号码的最前面的号码
*/
package cn.itcast.Mr_Zhang.BankQueue;

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

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

/*
* 产生一个号码,代表一个用户取号 因为产生号码和获取号码是不同线程对同一个数据进行操作,这样会产生问题,必须让他们互斥,所以加入同步
*/
public synchronized Integer generateNumber() {
queueNumber.add(lastNumber);
return lastNumber++;
}

/* 窗口取得一个号码,代表依次为客户服务 */
public synchronized Integer fetchNumber() {
Integer number = null;
if (queueNumber.size() > 0)
number = queueNumber.remove(0);
return number;
}
}


NumberMechine:号码机器

/*
* 1.整个系统中,取号机器只有一台,所以要设计成单例模式
* 2.该类中应该提供通过反问该类对象返回三个数字管理器对象的方法
*/
package cn.itcast.Mr_Zhang.BankQueue;

public class NumberMechine {

/*构造函数私有化,禁止外部创建对象*/
private NumberMechine(){

}

/*为外部提供一个访问本类对象的方法*/
private static final NumberMechine instance = new NumberMechine();
public static NumberMechine getNumberMechine(){
return instance;
}

/*创建普通、快速、VIP数字管理器对象并提供外部访问方法*/
private NumberManager commonNumber = new NumberManager();
private NumberManager expressNumber = new NumberManager();
private NumberManager VipNumber = new NumberManager();

public NumberManager getCommonNumber() {
return commonNumber;
}
public NumberManager getExpressNumber() {
return expressNumber;
}
public NumberManager getVipNumber() {
return VipNumber;
}

}


Constants:常量

package cn.itcast.Mr_Zhang.BankQueue;

public class Constants {
public static final int SERVICE_TIME_MIN = 1000;
public static final int SERVICE_TIME_MAX = 10000;
public static final int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}


mainClass:模拟运行系统

package cn.itcast.Mr_Zhang.BankQueue;

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

public class mainClass {
public static void main(String[] args) {

/*生成4个普通窗口并开启*/
for(int i = 1; i<=4; i++){
ServiceWindows commonWindow = new ServiceWindows();
commonWindow.setType(CustomerType.COMMON);
commonWindow.setWindowId(i);
commonWindow.start();
}

/*生成1个快速窗口并开启*/
ServiceWindows expressWindow = new ServiceWindows();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();

/*生成1个VIP窗口并开启*/
ServiceWindows vipWindow = new ServiceWindows();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();

/*按频率增加普通客户*/
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMechine.getNumberMechine().getCommonNumber().generateNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);

/*按频率增加快速客户*/
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMechine.getNumberMechine().getExpressNumber().generateNumber();
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 = NumberMechine.getNumberMechine().getVipNumber().generateNumber();
System.out.println("第" + serviceNumber + "号VIP客户正在等待服务");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS);
}
}


----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: