银行业务调度系统


银行业务调度系统
1.需求

1)银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
2)有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
3)异步随机生成各种类型的客户,生成各类型用户的概率比例为:
   VIP客户 :普通客户 :快速客户  =  1 :6 :3。
4)客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户
   办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可
   通过线程Sleep的方式模拟)。
5)各类型客户在其对应窗口按顺序依次办理业务。 
6)当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以
   处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
7)随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
   通过Log方式展现程序运行结果。

2.需求分析



2.1面向对象分析与设计

1)有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,
  各类型客户在其对应窗口按顺序依次办理业务 。
  1 首先,经常在银行办理业务的人更有利于理解本系统,例如,我经常陪老婆跑银行,对银行的这个业务
    算是比较熟悉了,我知道每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,
    我想到要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。
  2 由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码
    管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,
    这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。
2)各类型客户在其对应窗口按顺序依次办理业务 ,准确地说,应该是窗口依次叫号。
  1 各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码
    管理器获取当前要被服务的号码。
  2 如果我不是多次亲身经历银行的这种业务,再加之积累了大量面向对象的应用开发经验,我也
    不知道能否轻松进行这种设计,能否发掘出其中隐含的对象信息,我真说不出具体的经验是什么,
    就是日积月累出来的一种感觉。难道这就是传说中的:“只可意会,不可言传?”


2.2 对象分析

一共有 5个类
分别是 
NumberManager  号码管理器
NumberMachine  号码机器 
ServiceWindow  窗口
CustomerType   窗口类型 枚举对象
Constants      常量接口


NumberMachine  机器只有一个 设计成单例模式,用来管理NumberManager
一般我们都知道 银行的机器上有3个选项 vip 快速 普通
我们将这3个设计成3个 号码管理器 不同的 管理器管理自己的号码对象
NumberManager  拥有生成获取用户号码的功能
ServiceWindow  不同的窗口类型处理不同等级的用户逻辑
CustomerType   窗口对象
Constants      存储号码生成时间,窗口处理用户时间


3.代码实现

package cn.itcast.bank;


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


/**
 * 号码管理器
 * 普通客户分发处理
 * 快速客户分发处理
 * VIP客户处理
 * @author 李昂志
 */
public class NumberManager {
	private int newNumber;
	//保存号码的集合
	private List<Integer> qure = new ArrayList<Integer>();
	/**
	 * 生成号码
	 * @return
	 */
	public synchronized Integer createNewNumber(){
		qure.add(++newNumber);
		return newNumber;
	}
	/**
	 * 获取号码
	 * @return
	 */
	public synchronized Integer getServiceNumber(){
		if(qure.size()>0){
			return qure.remove(0);
		}
		return null;
	}
}

package cn.itcast.bank;


/**
 * 号码生成机器 管理号码
 * 号码机器唯一 生成号码 可以生成3种号码 普通客户 快速客户 vip客户
 * @author 李昂志
 */
public class NumberMachine {
	private static NumberMachine instance = new NumberMachine();
	private NumberManager commonUser;
	private NumberManager fastUser;
	private NumberManager vipUser;
	
	private NumberMachine(){
		commonUser = new NumberManager();
		fastUser =new NumberManager();
		vipUser = new NumberManager();
	}
	public static NumberMachine getSingleton(){
		return instance;
	}
	public NumberManager getCommonUser() {
		return commonUser;
	}
	public NumberManager getFastUser() {
		return fastUser;
	}
	public NumberManager getVipUser() {
		return vipUser;
	}
}


package cn.itcast.bank;


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


/**
 * 窗口服务类 分别为 普通服务 快速服务 vip服务
 * @author 李昂志
 */
public class ServiceWindow {
	private CustomerType customer; //用户类别
	private int number = 1;   //窗口号
	//初始化服务的时候 获取窗口类型
	public ServiceWindow(CustomerType customer){
		this.customer = customer;
	}
	//设置窗口号
	public void setNumber(int number){
		this.number = number;
	}
	public void start(){
		//各个窗口同步进行数据处理
		Executors.newSingleThreadExecutor().execute(
				new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						do{
							switch(customer){
								case COMMON:
									commerService();
									break;
								case FAST:
									fastService();
									break;
								case VIP:
									vipService();
									break;
						}}while(true);
					}
				}
				);
	}
	/**
	 * vip服务
	 */
	private void vipService() {
		// TODO Auto-generated method stub
		String windowName = this.number +" 号 "+customer.toString()+" 窗口";
		System.out.println(windowName+"为您服务,开始获取顾客号码 :");
		Integer number = NumberMachine.getSingleton().getVipUser().getServiceNumber();
		if(number != null){
			System.out.println(windowName+"为"+number+"号vip客户开始服务!............................");
			try {
				Thread.sleep(Constants.MIN_SERVICE_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName+"为"+number+"号用户完成vip服务  花费时间:"+Constants.MIN_SERVICE_TIME+" 耗秒");
		}else{
			System.out.println(windowName+"没有vip客户 获取普通客户号码....");
			commerService();
		}
	}
	/**
	 * 快速用户服务
	 */
	private void fastService() {
		// TODO Auto-generated method stub
		String windowName = this.number +" 号 "+customer.toString()+" 窗口";
		System.out.println(windowName+"开始获取顾客号码 :");
		Integer number = NumberMachine.getSingleton().getFastUser().getServiceNumber();
		if(number != null){
			System.out.println(windowName+"为"+number+"号快速客户开始服务!............................");
			try {
				Thread.sleep(Constants.MIN_SERVICE_TIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName+"为"+number+"号用户完成快速服务  花费时间:"+Constants.MIN_SERVICE_TIME+" 耗秒");
		}else{
			System.out.println(windowName+"没有快速客户 获取普通客户号码....");
			commerService();
		}
	}
	/**
	 * 普通用户服务
	 */
	private void commerService() {
		// TODO Auto-generated method stub
		String windowName = this.number +" 号 "+customer.toString()+" 窗口";
		System.out.println(windowName+"为您服务,开始获取顾客号码 :");
		Integer number = NumberMachine.getSingleton().getCommonUser().getServiceNumber();
		if(number != null){
			System.out.println(windowName+"为"+number+"号普通客户开始服务!............................");
			int time = new Random().nextInt(Constants.MAX_SERVICE_TIME/1000)+Constants.MIN_SERVICE_TIME/1000;
			try {
				Thread.sleep(time*1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(windowName + "为"+number+"号用户完成普通服务  花费时间:"+time+" 秒");
		}else{
			System.out.println(windowName+"没有普通客户....休息一秒");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}



package cn.itcast.bank;


/**
 * 顾客类型
 * @author 李昂志
 */
public enum CustomerType {
	COMMON,FAST,VIP;
	public String toString(){
		switch(this){
		case COMMON:
			return "普通";
		case FAST:
			return "快速";
		case VIP:
			return name();
		}
		return null;
	}
}




package cn.itcast.bank;


/**
 * 常量接口
 * @author 李昂志
 *
 */
public interface Constants {
	 int MAX_SERVICE_TIME = 10000; //10秒!最大处理时间
	 int MIN_SERVICE_TIME = 1000; //1秒!   最小处理时间
	 /*每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来
		 * 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户,所以,
		 * 1秒钟产生一个普通客户比较合理,*/
	 int COMMON_CUSTOMER_INTERVAL_TIME = 1; 	//产生普通用户时间
}

//启动类
package cn.itcast.bank;


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


public class Start {
	/**
	 * 1.先生成窗口
	 * 2.用户来拿号码
	 * @param args
	 */
	public static void main(String[] args) {
		int i =1;
		//生成四个普通窗口
		for(;i<5;i++){
			ServiceWindow coms = new ServiceWindow(CustomerType.COMMON);
			coms.setNumber(i);
			coms.start();
		}
		//生成一个快速窗口
		ServiceWindow fast = new ServiceWindow(CustomerType.FAST);
		fast.setNumber(i++);
		fast.start();
		//生成一个vip窗口
		ServiceWindow vip = new ServiceWindow(CustomerType.VIP);
		vip.setNumber(i++);
		vip.start();
		//普通用户拿号
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						int i = NumberMachine.getSingleton().getCommonUser().createNewNumber();
						System.out.println("普通客户获取第 "+i +" 号码 在排队等候服务中......");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME, 
				TimeUnit.SECONDS);
		//快速客户拿号  3秒生成一个客户
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						int i = NumberMachine.getSingleton().getFastUser().createNewNumber();
						System.out.println("快速客户获取第 "+i +" 号码 在排队等候服务中......");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME*3, 
				TimeUnit.SECONDS);
		//vip客户拿号 6秒生成一个vip客户
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						// TODO Auto-generated method stub
						int i = NumberMachine.getSingleton().getVipUser().createNewNumber();
						System.out.println("VIP客户获取第 "+i +" 号码 在排队等候服务中......");
					}
				}, 
				0, 
				Constants.COMMON_CUSTOMER_INTERVAL_TIME*6, 
				TimeUnit.SECONDS);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值