----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
银行业务调度系统需求:
模拟实现银行业务调度系统逻辑,具体需求如下:
银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
需求分析:
客户分为三种 VIP客户,普通客户,快速客户,他们进入银行取得号码,当其号码被叫到才能被服务;
银行的取号机只有一个,不同客户可按取号机上的不同选项取得号码;
可设计一个号码机NumberMachine来管理三个产生不同客户号码的号码管理器NumberManager,因为要只有一个要被设计成单例;银行服务窗口ServiceWindow
客户类Customer,表示三种不同客户的枚举类 CustomerType COMMON,EXPRESS,VIP
逻辑设计:
NumberManager类:
构造方法:
public NumberManager(CustomerType type,long generateNumberRate)
{
this.type = type;
this.generateNumberRate = generateNumberRate;
}
字段: private CustomerType type; //初始化的参数用以区分号码管理器类型
private int customerId =1;
private long generateNumberRate;//产生号码的比率
private List<Customer> customerQueue = new ArrayList<Customer>();//用于存放产生的客户号码的容器用与模拟队列
方法:
public void generateNewNumber()//此方法内用一个定时器线程,隔一段时间产生一个号码
public synchronized Customer fetchServiceNumber()//获取队列中的第一元素,就是排在最前面的客户,它被多线程访问,所以要被设计成同步的方法
NumberMachine类:
字段:三个不同客户的NumberManager
private NumberManager commonNumberManager = new NumberManager(CustomerType.COMMON,1);
private NumberManager expressNumberManager = new NumberManager(CustomerType.EXPRESS,3);
private NumberManager vipNumberManager = new NumberManager(CustomerType.VIP,9);
方法:
public void generateCustomerNumber()//使号码产生器产生号码,里面调用的是NumberManager的public void generateNewNumber()方法
public Customer getCommonNumber()//获得普通客户队列中的第一个位置的客户
public Customer getExpressNumber()//获得快速客户队列中的第一个位置的客户
public Customer getVipNumber()//获得Vip客户队列中的第一个位置的客户
Customer类:
构造方法:
public Customer(CustomerType type,int customerId)
字段:
private CustomerType type;//用来标识不用类型的客户
private int customerId;//用来标识同一类型的第几号客户
static int serviceMAXTime = 10000;//客户处理自身业务所需时间的最大值
static int serviceMINTime = 1000;//客户处理自身业务所需时间的最小值
private int taketime;//处理自身业务所用的实际时间
方法:
public void getService()//表示用户被服务
public void serviceOver()//表示用户的业务处理结束
private int setTakeTime()//用于客户对象建立时初始化字段taketime
public int getTakeTime()//用于获取客户的业务处理岁消耗的时间
ServiceWindow类:
字段:
private CustomerType type;//初始化标识不同种类的窗口
private int windonwId;//初始化时标识窗口的序号
方法:
public void start()//内部启动一个线程来循环获取客户,为客户服务
编码:
CsutomerType枚举类:
package com.qiufeng.bank;
public enum CustomerType {
COMMON,EXPRESS,VIP;
}
Customer类:
package com.qiufeng.bank;
import java.util.Random;
public class Customer {
private CustomerType type;
private int customerId;
static int serviceMAXTime = 10000;;
static int serviceMINTime = 1000;
private int taketime;
public Customer(CustomerType type,int customerId)
{
this.type = type;
this.customerId = customerId;
this.taketime = setTakeTime();
}
public void getService(){
System.out.println( type.name()+"型第"+this.customerId+"号客户正在被服务");
}
public void serviceOver()
{
System.out.println(type.name()+"型第"+this.customerId+"号客户的业务办理完成"+"耗时"+taketime/1000+"秒");
}
private int setTakeTime()
{
if(this.type==CustomerType.EXPRESS)
{
return this.serviceMINTime;
}
return (new Random().nextInt(serviceMAXTime-serviceMINTime)+1+this.serviceMINTime);
}
public int getTakeTime()
{
return this.taketime;
}
public String toString()
{
return this.type.name()+"型第"+this.customerId+"号客户";
}
}
NumberManger类:
package com.qiufeng.bank;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NumberManager {
private CustomerType type;
private int customerId =1;
private long generateNumberRate;
private List<Customer> customerQueue = new ArrayList<Customer>();
public void generateNewNumber()
{
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run()
{
Customer c = new Customer(type,customerId++);
customerQueue.add(c);
//System.out.println(type.name());
// System.out.println(type.name()+customerQueue.size());
}
},
0,
generateNumberRate,
TimeUnit.SECONDS);
}
public synchronized Customer fetchServiceNumber()
{ //System.out.println(type.name()+customerQueue.size());
if(customerQueue.size()>0)
{
return customerQueue.remove(0);
}
return null;
}
public NumberManager(CustomerType type,long generateNumberRate)
{
this.type = type;
this.generateNumberRate = generateNumberRate;
}
public void setGenerateNumberRate(long generateNumberRate) {
this.generateNumberRate = generateNumberRate;
}
}
NumberMachine类:
package com.qiufeng.bank;
public class NumberMachine {
private NumberManager commonNumberManager = new NumberManager(CustomerType.COMMON,1);
private NumberManager expressNumberManager = new NumberManager(CustomerType.EXPRESS,3);
private NumberManager vipNumberManager = new NumberManager(CustomerType.VIP,9);
public NumberManager getCommonNumberManager() {
return commonNumberManager;
}
public NumberManager getExpressNumberManager() {
return expressNumberManager;
}
public NumberManager getVipNumberManager() {
return vipNumberManager;
}
private static NumberMachine instance = new NumberMachine();
private NumberMachine()
{
}
public void generateCustomerNumber()
{
this.getCommonNumberManager().generateNewNumber();
this.getExpressNumberManager().generateNewNumber();
this.getVipNumberManager().generateNewNumber();
}
public Customer getCommonNumber()
{
return this.getCommonNumberManager().fetchServiceNumber();
}
public Customer getExpressNumber()
{
return this.expressNumberManager.fetchServiceNumber();
}
public Customer getVipNumber()
{
return this.getVipNumberManager().fetchServiceNumber();
}
public static NumberMachine getInstance()
{
return instance;
}
}
ServiceWindow类:
package com.qiufeng.bank;
import java.util.concurrent.Executors;;
public class ServiceWindow {
private CustomerType type;
private int windonwId;
static NumberMachine instance = NumberMachine.getInstance();
public ServiceWindow(CustomerType type,int windowId)
{
this.type = type;
this.windonwId = windowId;
}
public void setType(CustomerType type) {
this.type = type;
}
public void setWindonwId(int windonwId) {
this.windonwId = windonwId;
}
public void start()
{
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run()
{
while(true)
{
switch(type)
{
case VIP:
Service(CustomerType.VIP);
break;
case EXPRESS:
Service(CustomerType.EXPRESS);
break;
case COMMON:
Service(CustomerType.COMMON);
break;
}
}
}
});
}
private void Service(CustomerType type) {
Customer customer = getCustomer(type);
if(customer!=null)
{System.out.println("您好!尊敬的"+customer+"这里是"+this.type.name()+"型"+this.windonwId+"号窗口我即将为你服务");
customer.getService();
try {
Thread.sleep(customer.getTakeTime());
} catch (InterruptedException e) {
e.printStackTrace();
}
customer.serviceOver();
}
else{
System.out.println(this.type.name()+"型"+this.windonwId+"号窗口空闲,休息一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Customer getCustomer(CustomerType type)
{
Customer customer =null;
switch(type)
{
case VIP:
customer = instance.getVipNumber();
if(customer==null)
{
customer = instance.getCommonNumber();
}
break;
case EXPRESS:
customer = instance.getExpressNumber();
if(customer==null)
{
customer = instance.getCommonNumber();
}
break;
case COMMON:
customer = instance.getCommonNumber();
break;
}
return customer;
}
}
运行MainClass:
package com.qiufeng.bank;
public class MainClass {
public static void main(String[] args) {
NumberMachine.getInstance().generateCustomerNumber();
for(int i= 1;i<=4;i++)
{
new ServiceWindow(CustomerType.COMMON,i).start();
}
new ServiceWindow(CustomerType.EXPRESS,5).start();
new ServiceWindow(CustomerType.VIP,6).start();
}
}
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------