银行业务调度系统

一、需求分析

1、项目需求

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

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

(2)    有3种业务类型:普通用户,快速用户(如办理水电费,电话费之类的业务),VIP用户。

(3)    异步随机生成各种类型的客户,生成的客户类型比为。

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

(4)    客户办理业务所需时间有最大最小值,VIP和普通客户办理时间为最大最小值范围内的随机值,快速客户办理业务的时间为最小值最大最小值自定。

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

(6)    当VIP窗口和快速窗口没有对应的业务时,可办理普通客户业务,一旦有对应业务,则优先办理对应业务。

(7)    随机生成客户时间间隔自定。

(8)    不需要实现GUI,只考虑逻辑实现,通过Log方式展现程序运行结果。

2、面向对象设计与分析

(1)    首先通过需求,提取类和对象的信息。

VIP客户,普通客户,快速客户 ,是异步随机生成的客户,各客户优先在其对应窗口按顺序依次办理业务。其实每一个客户就是由银行的一个取号机器产生的方式来表示的。所以,要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机的生成了客户。

(2)    由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。

(3)    各类型客户在其对应窗口按顺序依次办理业务,准确地说,应该是窗口依次叫号。之所以各个窗口知道叫哪一个号,它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

(4)    类图

画图非常有助于理解和分析问题,类图把整个程序结构给清晰的展现,如下:



二、代码设计与编写

1、首先编写设计NumberManager类模拟产生各种类型的客户。

实现功能1:产生客户号码存储到List集合,模拟客户按号排队等待

实现功能2:取出客户号码,即将List集合中的号码移除并返回号码,模拟叫号为客户号码服务

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

package com.isoftstone.interviev.bank;

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

public class NumberManager {
	private int lastNumber = 1;
	private List<Integer> queueNumber = new ArrayList<Integer>();
	public synchronized Integer generateNewManager(){
		queueNumber.add(lastNumber);
		return lastNumber++;
	}
	
	public synchronized Integer fetchServiceNumbr(){
		Integer nuber = null;
		if(queueNumber.size()>0)
			nuber = queueNumber.remove(0);
		return nuber;
	}
}


 2、编写设计NumberMachine类

(1)保证对象的唯一性,涉及单例模式, 使用单例设计模式设计此类。

(2)实现功能1:管理产生各种客户类型号码的NumberMachine类实例对象,并提供对公共方法返回这些实例对象

package com.isoftstone.interviev.bank;

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

public class NumberManager {
	private int lastNumber = 1;
	private List<Integer> queueNumber = new ArrayList<Integer>();
	public synchronized Integer generateNewManager(){
		queueNumber.add(lastNumber);
		return lastNumber++;
	}
	
	public synchronized Integer fetchServiceNumbr(){
		Integer nuber = null;
		if(queueNumber.size()>0)
			nuber = queueNumber.remove(0);
		return nuber;
	}
}

3、编写银行业务服务窗口ServiceWindow类

实现功能1:启动业务窗口,定义不同类型客户的对应的服务流程方法

实现功能2:判断客户类型,并优先办理与窗口对应类型的客户的业务

package com.isoftstone.interviev.bank;

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

public class ServiceWindow {
	private CustomerType type = CustomerType.COMMON;
	private int windowId = 1;
	
	public void setType(CustomerType type) {
		this.type = type;
	}
	public void setWindowId(int windowId) {
		this.windowId = windowId;
	}

	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() {
				String windowName = "第"+windowId+"号"+type+"窗口";
				Integer servicenumber = NumberMachine.getInstance().getCommonManager().fetchServiceNumbr();
				System.out.println(windowName+"正在获取任务");
				if(servicenumber != null){
					System.out.println(windowName+"为第"+servicenumber+"个"+"普通"+"客户服务");
					long geginTime = System.currentTimeMillis();
					int maxRand = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;
					long serveTime = new Random().nextInt(maxRand)+1+Constans.MIN_SERVICE_TIME;
					try {
						Thread.sleep(serveTime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				    long cosetTime = System.currentTimeMillis()-geginTime;
					System.out.println(windowName+"为第"+servicenumber+"个"+"普通"+"客户完成服务,耗时"+serveTime/1000+"秒");
				}else{
				     System.out.println(windowName+"没有取到任务,先休息一秒");
				     try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
				}
			}
			
			private void expressService() {
				String windowName = "第"+windowId+"号"+type+"窗口";
				Integer servicenumber = NumberMachine.getInstance().getExpressManager().fetchServiceNumbr();
				System.out.println(windowName+"正在获取任务");
				if(servicenumber != null){
					System.out.println(windowName+"为第"+servicenumber+"个"+type+"客户服务");				
					long geginTime = System.currentTimeMillis();
					try {
						Thread.sleep(Constans.MIN_SERVICE_TIME);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				    long cosetTime = System.currentTimeMillis()-geginTime;
					System.out.println(windowName+"为第"+servicenumber+"个"+type+"客户完成服务,耗时"+cosetTime/1000+"秒");
				}else{
				     System.out.println(windowName+"没有取到任务");
				     commonService();
				}
			}
			private void VIPService() {
				String windowName = "第"+windowId+"号"+type+"窗口";
				Integer servicenumber = NumberMachine.getInstance().getVIPManager().fetchServiceNumbr();
				System.out.println(windowName+"正在获取任务");
				if(servicenumber != null){
					System.out.println(windowName+"为第"+servicenumber+"个"+type+"客户服务");				
					long geginTime = System.currentTimeMillis();
					int maxServeTime = Constans.MAX_SERVICE_TIME - Constans.MIN_SERVICE_TIME;
					long serveTime = new Random().nextInt(maxServeTime)+1+Constans.MIN_SERVICE_TIME;
					try {
						Thread.sleep(serveTime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				    long cosetTime = System.currentTimeMillis()-geginTime;
					System.out.println(windowName+"为第"+servicenumber+"个"+type+"客户完成服务,耗时"+cosetTime/1000+"秒");
				}else{
				     System.out.println(windowName+"没有取到任务");
				     commonService();
				}
			}
}

4、编写设计客户类型类_使用了具有高安全性的枚举类实现

package com.isoftstone.interviev.bank;

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

 

5、编写设计业务服务时间最值常量Constans类


package com.isoftstone.interviev.bank;

import java.util.concurrent.TimeUnit;

public class Constans {

	public static int MAX_SERVICE_TIME = 10000;
	public static int MIN_SERVICE_TIME = 1000;
	public static int COMMON_CUSTOMER_INTERVAL_TLME = 1;
}

6、编写设计主测试MainClass类

创建各种类型业务窗口实例对象,启动窗口,开始叫号

异步增加不同类型的客户号码

package com.isoftstone.interviev.bank;

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

public class MainClass {

	public static void main(String[] args) {
		for(int i=1;i<5;i++){
			ServiceWindow commonwindow = new ServiceWindow();
			commonwindow.setWindowId(i);
			commonwindow.start();
		}
		
		ServiceWindow expresswindow = new ServiceWindow();
		expresswindow.setType(CustomerType.EXPRESS);
		expresswindow.start();
		
		ServiceWindow vipwindow = new ServiceWindow();
		vipwindow.setType(CustomerType.VIP);
		vipwindow.start();
		
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
				public void run(){
					Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager();
					System.out.println(number + "号普通客户等待服务");
				}
				},
				0,
				Constans.COMMON_CUSTOMER_INTERVAL_TLME*3, 
				TimeUnit.SECONDS
				);
		
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
				public void run(){
					Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager();
					System.out.println(number + "号快速客户等待服务");
				}
				},
				0,
				Constans.COMMON_CUSTOMER_INTERVAL_TLME*2, 
				TimeUnit.SECONDS
				);
		
		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
				new Runnable(){
				public void run(){
					Integer number = NumberMachine.getInstance().getVIPManager().generateNewManager();
					System.out.println(number + "号VIP客户等待服务");
				}
				},
				0,
				Constans.COMMON_CUSTOMER_INTERVAL_TLME*6, 
				TimeUnit.SECONDS
				);
	}
} 

三、总结

1、面向对象的一个思维方式:谁拥有数据,谁就对外提供操作这些数据的方法。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值