银行业务调度系统
模拟实现银行业务调度系统逻辑,具体需求如下:
Ø 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
Ø 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
Ø 异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
Ø 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
Ø 各类型客户在其对应窗口按顺序依次办理业务。
Ø 当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
Ø 随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
学习笔记:
熟悉了题目要求后,首先要完成的就是该系统的结构,是如何连系的,有那些对象?这些对象之间是什么关系?明白了这些,程序就好完成了。
首先,有客户来,会要求先取号,取号后判断其是什么类型的客户,所以取号机应该有三种选择,取号机保存所选取的信息,此时,由服务窗口去访问取号机,是否有人取了号,如有,则通知其过来办理业务。
所以,这个系统中的对象应该有:取号机、服务窗口
取号机-->产生三种类型的客户:有三种选择,即产生三种类型客户,那么可以让取号机做成单例模型。
服务窗口--> 4个普通窗口 :只处理普通客户
--> 一个快速窗口 :处理快速客户,如果此时没有快速客户,那么去处理普通客户,处理完一个要先检查是否有快速客户。
--> VIP窗口: 处理VIP客户,如果此时没有VIP客户,那么去处理 普通客户,处理完一个要先检查是否有快速客户。
取号机保存客户取号信息:
有人来取号,并取的是什么类型号,由取号机保存。
public class NumberManage {
//用于保存客户取号记录
private List manage = new ArrayList();
//现在是第几位客户
private int lastcustomer = 0;
//来人取号
public synchronized Integer addNumber()
{
manage.add(++lastcustomer);
return lastcustomer;
}
//取客户,为其处理业务,也就得删除一个取号记录
public synchronized Integer delePerson()
{
//处理前得看是否有人在等待
if(manage.size()>0)
return (Integer)manage.remove(0);
return null;
}
}
取号机:
因为取号机只有三种选择,所以可以做成单例。做成单例后呢,那么客户就得让主函数来产生了,不然应该是由取号机产生的。
在这个单例里,返回三种客户类型。分别保存了不同类型的客户。
public class NumberMachine {
private NumberMachine(){}
private static NumberMachine number = new NumberMachine();
public static NumberMachine getIntance(){
return number;
}
//取号机的三种选择
private NumberManage commoncustomer = new NumberManage();
private NumberManage quickcustomer = new NumberManage();
private NumberManage vipcustomer = new NumberManage();
public NumberManage getcommoncustomer()
{
return commoncustomer;
}
public NumberManage getquickcustomer()
{
return quickcustomer;
}
public NumberManage getvipcustomer()
{
return vipcustomer;
}
}
如何产生客户呢?
使用线程池,让其不断产生,使用Executors 类来完成
//产生普通客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run()
{
NumberMachine.getIntance().getcommoncustomer().addNumber();
}
},
1,
ConfigureFile.COMMON_CUSTOMER_APPEAR_TIME,
TimeUnit.SECONDS
);
产生一个VIP窗口。
//产生一个VIP窗口
ServeWindow sw3 = new ServeWindow();
sw3.setWindowNumber(6);
sw3.setWindowType(WindowType.VIP_WINDOW);
窗口如何获取任务?
通过访问取号机,看取号机里是否有人取过号。
Integer getnumber = NumberMachine.getIntance().getcommoncustomer().delePerson();
如果返回有数据,说明有客户。
怎么处理任务的呢?
处理任务就是让其Thread.sleep()一会就行,处理一个后,删除保存在集合中的数据。采用先进先出的方式,每次删除第一个元素即可。
窗口类型因为是固定那三种,所以我们可以设置成枚举类型。
用其它方法当然也可以,但是用这个更专业。
public enum WindowType {
COMMON_WINDOW,QUICK_WINDOW,VIP_WINDOW;
//重写 toString() 方法
public String toString()
{
if(this == COMMON_WINDOW)
return "普通";
else if(this == QUICK_WINDOW)
return "快速";
else
return "VIP";
}
}
心得:
要做好一个项目,还是对象很重要,只要明白了是由那些对象来完成的,那么就好做了,对于操作的数据应该分配给谁呢?谁拥有数据,谁就提供操作数据 的方法。在这个程序中,使用到了枚举,单例,线程池,随机数。对于一些对象中如果 它的元素是固定的那么几种,那么可以用枚举来实现,如题中,窗口的类型。