银行业务调度系统——面向对象的分析和设计
分析:
1.因为各类型客户在其对应窗口按顺序依次办理业务,即每一个客户其实是由银行的一个取号机器产生号码的方式来表示的。
所以,需要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。
2.因为有三种客户,而且各自都有自己的服务窗口,即独立的,所以需要三个号码管理器对象来分别管理,而且这三个统一由
一个号码机器管理,因此号码机器需要设计为单例;
3.服务窗口每次都要通过号码机器来获取当前自己要被服务的号码。
4.所需要的对象:
NumberMachine中:定义三个成员变量分别指向三个NumberManager对象;
getCommonManager():返回普通客户的号码管理器;
getVipManager():返回VIP客户的号码管理器;
getExpressManager():返回快速客户的号码管理器;
NumberManager中:定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合;
generateNumber():返回给客户产生的新号码;
fetchNumber():返回给服务窗口取号;
ServiceWindow中:定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。
start():开始服务;
commonService():普通客户服务窗口;
vipService():VIP客户服务窗口;
expressService():快速客户服务窗口;
CustomerType枚举类:
系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。
重写toString方法,返回类型的中文名称。这是在后面编码时重构出来的,刚开始不用考虑。
Constants类:定义客户办理所需最长服务时间和最短服务时间以及客户等待时间间隔;
定义三个常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME
5.类的代码的实现:
1.NumberManager类:号码管理器
<span style="font-size:12px;"><span style="font-family: 'Microsoft YaHei';"> </span><span style="font-family:Arial;">import java.util.ArrayList;
import java.util.List;
//由于类中的两个方法,是两个不同的线程在操作,所以需要用到synchronized.
class NumberManager {
private int lastNumber = 0;
private List queueNumbers = new ArrayList();
//产生新号码给客户
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;
}
}
}</span></span>
2.NumberMachine类:号码机器,内部管理号码管理器
<span style="font-size:12px;"><span style="font-family:Arial;"><span> </span>class NumberMachine {
<span> </span>//在系统只能有一个,因此用到单例,私有化构造函数
<span> </span>private NumberMachine(){}
<span> </span>//饿汉式,较懒汉式安全
<span> </span>private static NumberMachine instance = new NumberMachine();
<span> </span>public static NumberMachine getInstance(){
<span> </span> <span> </span>return instance;
<span> </span> }
<span> </span>//建立号码管理器对象
<span> </span>private NumberManager commonManager = new NumberManager();
<span> </span>private NumberManager expressManager = new NumberManager();
<span> </span>private NumberManager vipManager = new NumberManager();
<span> </span>public NumberManager getCommonManager() {
<span> </span>return commonManager;
<span> </span>}
<span> </span>public NumberManager getExpressManager() {
<span> </span>return expressManager;
<span> </span>}
<span> </span>public NumberManager getVipManager() {
<span> </span>return vipManager;
<span> </span>}
<span> </span>}
</span></span>
3.ServiceWindow:服务窗口
<span style="font-size:12px;"><span style="font-family:Arial;"><span> </span>import java.util.Random;
<span> </span>import java.util.concurrent.Executors;
<span> </span>import java.util.logging.Logger;
<span> </span>class ServiceWindow {
<span> </span>private static Logger logger = Logger.getLogger("1.txt");
<span> </span>//默认的服务窗口为普通窗口
<span> </span>private CustomerType type = CustomerType.COMMON;
<span> </span>private int number = 1;
<span> </span>//获取服务窗口
<span> </span>public CustomerType getType() {
<span> </span>return type;
<span> </span>}
<span> </span>//设置服务窗口
<span> </span>public void setType(CustomerType type) {
<span> </span>this.type = type;
<span> </span>}
<span> </span>//设置窗口号
<span> </span>public void setNumber(int number){
<span> </span>this.number = number;
<span> </span>}
<span> </span>//开启线程
<span> </span>public void start(){
<span> </span>Executors.newSingleThreadExecutor().execute(
<span> </span>new Runnable(){
<span> </span>public void run(){
<span> </span>while(true){
<span> </span>//根据类型选择服务窗口
<span> </span> switch(type){
<span> </span> case COMMON:
<span> </span> commonService();
<span> </span> break;
<span> </span>case EXPRESS:
<span> </span>expressService();
<span> </span> break;
<span> </span>case VIP:
<span> </span> vipService();
<span> </span>break;
<span> </span>}
<span> </span>}
<span> </span>}
<span> </span>}
<span> </span>);
<span> </span>}
<span> </span>//普通客户服务
<span> </span>private void commonService(){
<span> </span>String windowName = "第" + number + "号" + type + "窗口";
<span> </span>System.out.println(windowName + "开始获取普通任务!");
<span> </span>//服务窗口取号
<span> </span> Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
<span> </span>if(serviceNumber != null ){
<span> </span>System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");
<span> </span>int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
<span> </span>//服务时间期间,休息时间为1秒到10秒
<span> </span>int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
<span> </span>try {
Thread.sleep(serviceTime);
<span> </span>}catch (InterruptedException e) {
e.printStackTrace();
<span> </span>}
<span> </span>System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");
<span> </span>}else{
System.out.println(windowName + "没有取到普通任务,正在空闲一秒");
<span> </span>try {
Thread.sleep(1000);
<span> </span>} catch (InterruptedException e) {
e.printStackTrace();
<span> </span>}
<span> </span>}<span> </span>
<span> </span>}
<span> </span> //快速窗口
<span> </span>private void expressService(){
<span> </span>//快速窗口开始取号
<span> </span>Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();
<span> </span>String windowName = "第" + number + "号" + type + "窗口";
<span> </span>System.out.println(windowName + "开始获取快速任务!");
<span> </span>if(serviceNumber !=null){
System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务");
//快速窗口服务时间1秒
int serviceTime = 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 + "没有取到快速任务!");
//没有取到快速业务则获取普通任务
commonService();
<span> </span>}
<span> </span>}
<span> </span>//VIP窗口
<span> </span>private void vipService(){
<span> </span> //开始取号
<span> </span>Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();
<span> </span>String windowName = "第" + number + "号" + type + "窗口";
<span> </span>System.out.println(windowName + "开始获取VIP任务!");
<span> </span>if(serviceNumber !=null){
<span> </span>System.out.println(windowName + "开始为第" + serviceNumber + "号VIP客户服务");
<span> </span>int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
<span> </span>int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
<span> </span>try {
<span> </span>//线程正在服务期间
<span> </span>Thread.sleep(serviceTime);
<span> </span>} catch (InterruptedException e) {
<span> </span>e.printStackTrace();
<span> </span>}
<span> </span>System.out.println(windowName + "完成为第" + serviceNumber + "号VIP客户服务,总共耗时" + serviceTime/1000 + "秒"); <span> </span>}else{
<span> </span>System.out.println(windowName + "没有取到VIP任务!");
<span> </span>//没有获取到VIP任务时,继续获取普通任务
<span> </span>commonService();
<span> </span>}
<span> </span>}
<span> </span>}</span><span style="font-family:Microsoft YaHei;">
</span></span>
4.Constants类
<span style="font-size:12px;"><span style="font-family:Arial;"><span> </span>public class Constants {
<span> </span>//定义最长服务时间和最短服务时间,在1-10秒指甲
<span> </span>public static int MAX_SERVICE_TIME = 10000; //10秒!
<span> </span>public static int MIN_SERVICE_TIME = 1000; //1秒!
<span> </span>public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
<span> </span>}</span><span style="font-family:Microsoft YaHei;">
</span></span>
5.CustomerType类:
窗口的类型3种
<span style="font-size:12px;"><span style="font-family:Microsoft YaHei;"><span> </span>public enum CustomerType {
</span><span style="font-family:Arial;"> <span> </span>COMMON,EXPRESS,VIP;
<span> </span>public String toString(){
<span> </span> <span> </span>String name = null;
<span> </span>switch(this){
<span> </span>case COMMON:
<span> </span>name = "普通";
<span> </span>break;
<span> </span>case EXPRESS:
<span> </span>name = "快速";
<span> </span>break;
<span> </span>case VIP:
<span> </span> name = name();
<span> </span>break;
<span> </span>}
<span> </span>return name;
<span> </span>}
<span> </span>}<span> </span></span></span>
6.主函数运行
<span style="font-size:12px;"><span style="font-family:Arial;"><span> </span>import java.util.concurrent.Executors;
<span> </span>import java.util.concurrent.TimeUnit;
<span> </span>import java.util.logging.Logger;
<span> </span>public class MainClass {
<span> </span>public static void main(String[] args) {
<span> </span>//产生4个普通窗口
<span> </span>for(int i=1;i<5;i++){
<span> </span>ServiceWindow window = new ServiceWindow();
<span> </span>window.setNumber(i);
<span> </span>window.start();
<span> </span>}
<span> </span>//产生1个快速窗口
<span> </span>ServiceWindow expressWindow = new ServiceWindow();
<span> </span>expressWindow.setType(CustomerType.EXPRESS);
<span> </span>expressWindow.start();
<span> </span>//产生1个VIP窗口
<span> </span>ServiceWindow vipWindow = new ServiceWindow();
<span> </span>vipWindow.setType(CustomerType.VIP);
<span> </span>vipWindow.start();
<span> </span>//普通客户拿号
<span> </span>Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
<span> </span>new Runnable(){
<span> </span>public void run(){
<span> </span>//取号
<span> </span>Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
<span> </span>System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
<span> </span>}
<span> </span>},0,Constants.COMMON_CUSTOMER_INTERVAL_TIME,TimeUnit.SECONDS);
<span> </span>//快速客户拿号
<span> </span>Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
<span> </span>new Runnable(){
<span> </span> public void run(){
<span> </span>Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
<span> </span>System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
<span> </span>}
<span> </span>},0,Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,TimeUnit.SECONDS);
<span> </span>//VIP客户拿号
<span> </span>Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
<span> </span>new Runnable(){
<span> </span>public void run(){
<span> </span>Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
<span> </span>System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
<span> </span>}
<span> </span>},0,Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,TimeUnit.SECONDS);
<span> </span>}
<span> </span>}</span><span style="font-family:Microsoft YaHei;">
</span></span>