项目名称:银行业务调度系统
项目内容要求:
银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
用面向对象的方法分析:题目设计到的对象有窗口、出号码器、号码管理器他们之间的联系如图:
分析号码管理器:号码管理器主要用于产生号码和取出号码,因为号码是保持先进先出的原则,所以定义一个List集合用于存储号码。然后把最前面的号码取出。
代码如下:
importjava.util.ArrayList;
importjava.util.List;
publicclass NumberCollect {
private int number=0;
private List<Integer> number_list=new ArrayList<Integer>();
//产生号码
public synchronizedInteger conmuctionNumber(){
number_list.add(++number);//把号码添加到集合中。
return number;
}
//获取号码
public synchronizedInteger bankNumber(){
IntegernewNumber=null;
if(number_list.size()>0)
newNumber=(Integer)number_list.remove(0);//获取最前面的号码
return newNumber;
}
}
分析出号器:从名字就可以看出他的主要用途就是用户让客户取号排队,取号之前首先要有号,所以该类内部封装了号码管理器的对象。按题目有三种客户,那么就要有三个号码管理器的对象,分开管理。有利于管理维护。出号器只有一个,所以不能自主创建对象,且对象固定,想到用单例模式可以解决。
代码如下:
publicclass NumberMachion {
private NumberCollect common=new NumberCollect();//定义普通号码
private NumberCollect qucly=new NumberCollect();//定义快速号码
private NumberCollect VIP=new NumberCollect();//定义VIP号码
public NumberCollect getCommon() {
return common;
}
public NumberCollect getQucly() {
return qucly;
}
public NumberCollect getVIP() {
return VIP;
}
private NumberMachion(){}//私有构造函数,不让外界创建
private static NumberMachion numbermachion=newNumberMachion(); //自己创建
public static NumberMachion getNumberMachion(){//获取本类对象
return numbermachion;
}
}
分析窗口类:因为有三种不同的窗口,分别为:普通窗口、快速窗口、VIP窗口。他们都是固定的,把他们封装成了一个枚举类,定义窗口的服务对象及服务事件。
窗口类代码如下:
importjava.util.Random;
importjava.util.concurrent.Executors;
publicclass ServerWindow {
private int number=1;
private ConmuctionType type=ConmuctionType.common;
public void setNumber(intnumber) {
this.number = number;
}
public void setType(ConmuctionType type) {
this.type = type;
}
public void start(){
Executors.newSingleThreadExecutor().execute(
new Runnable(){
public void run(){
while(true){
switch(type){
case common:
commonServer();
break;
case qucly:
quclyServer();
break;
case VIP:
VIPServer();
break;
}
}
}
});
}
//为普通用户服务
private void commonServer() {
// TODOAuto-generated method stub
System.out.println("第"+number+"号"+type+"窗口正在为普通客户服务");
Integerconmuction=NumberMachion.getNumberMachion().getCommon().bankNumber();
if(conmuction!=null){
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号普通客户服务");
long servertime=(new Random().nextInt(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME))+1+StaticTime.SHRIT_TIME;
try {
Thread.sleep(servertime);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号普通客户服务...............结束");
}
else{
System.out.println("第"+number+"号"+type+"窗口没有取到普通任务........休息一秒");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
//为快速用户服务
private void quclyServer() {
// TODOAuto-generated method stub
System.out.println("第"+number+"号"+type+"窗口正在为快速客户服务");
Integerconmuction=NumberMachion.getNumberMachion().getQucly().bankNumber();
if(conmuction!=null){
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号快速客户服务");
//long servertime=(new Random().nextInt())*StaticTime.SHRIT_TIME+1+(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME);
try {
Thread.sleep(StaticTime.SHRIT_TIME);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号快速客户服务...............结束");
}
else{
System.out.println("第"+number+"号"+type+"窗口没有取到快速任务........休息一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
commonServer();
}
}
//为VIP窗口用户服务
private void VIPServer() {
// TODOAuto-generated method stub
System.out.println("第"+number+"号"+type+"窗口正在为VIP客户服务");
Integer conmuction=NumberMachion.getNumberMachion().getVIP().bankNumber();
if(conmuction!=null){
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号VIP客户服务");
long servertime=(new Random().nextInt(StaticTime.LONG_TIME-StaticTime.SHRIT_TIME))+1+StaticTime.SHRIT_TIME;
try {
Thread.sleep(servertime);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
System.out.println("第"+number+"号"+type+"窗口正在为第"+number+"号VIP客户服务...............结束");
}
else{
System.out.println("第"+number+"号"+type+"窗口没有取到VIP任务........休息一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
commonServer();
}
}
}
定义窗口类型及客户类型的类
代码如下:
publicenum ConmuctionType {
common,qucly,VIP;
public String toString(){
String name=null;
switch(this){
case common:
name="普通";
break;
case qucly:
name="快速";
break;
case VIP:
name="VIP";
break;
}
return name;
}
}
定义常量类:
代码如下:
publicclass StaticTime {
public static intLONG_TIME=10000;
public static intSHRIT_TIME=1000;
public static intconmuction_time=1;
}
测试类:
importjava.util.concurrent.Executors;
importjava.util.concurrent.TimeUnit;
publicclass MainClassDemo {
/**
* @param args
*/
public static voidmain(String[] args) {
// TODOAuto-generated method stub
for(int i = 1;i<5;i++){
ServerWindowsw=new ServerWindow(); //产生普通窗口
sw.setNumber(i);
sw.start();
}
//产生快速窗口
ServerWindowqucly=new ServerWindow();
qucly.setType(ConmuctionType.qucly);
qucly.start();
//产生VIP窗口
ServerWindow vip=newServerWindow();
vip.setType(ConmuctionType.VIP);
vip.start();
//模拟普通用户取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integernumber=NumberMachion.getNumberMachion().getCommon().conmuctionNumber();
System.out.println("第"+number+"号普通客户等待服务..");
}
},
0,
StaticTime.conmuction_time,
TimeUnit.SECONDS);
//模拟快速用户取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integernumber=NumberMachion.getNumberMachion().getQucly().conmuctionNumber();
System.out.println("第"+number+"号快速客户等待服务..");
}
},
0,
StaticTime.conmuction_time*2,
TimeUnit.SECONDS);
//模拟VIP用户取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integernumber=NumberMachion.getNumberMachion().getVIP().conmuctionNumber();
System.out.println("第"+number+"号VIP客户等待服务..");
}
},
0,
StaticTime.conmuction_time*6,
TimeUnit.SECONDS);
}
}
运行结果:
不足之处:号码管理器类,它是用来产生号码和取出号码,当他对外暴露时,会引起系统的安全隐患,如果有非法人员(或操作错误)可能会导致银行系统错乱,所以这个类应当进行隐藏。隐藏方法有:将其抽象化,将其变为接口,封装成出号器的内部类。我在这里将其抽象化。
号码管理器代码:
import java.util.ArrayList;
import java.util.List;
public abstract class NumberCollect {
private int number=0;
private List<Integer> number_list=new ArrayList<Integer>();
public synchronized Integer conmuctionNumber(){
number_list.add(++number);
return number;
}
public synchronized Integer bankNumber(){
Integer newNumber=null;
if(number_list.size()>0)
newNumber=(Integer)number_list.remove(0);
return newNumber;
}
}
出号器代码:
publicclass NumberMachion {
private NumberCollect common=new NumberCollect(){};
private NumberCollect qucly=new NumberCollect(){};
private NumberCollect VIP=new NumberCollect(){};
public NumberCollect getCommon() {
return common;
}
public NumberCollect getQucly() {
return qucly;
}
public NumberCollect getVIP() {
return VIP;
}
private NumberMachion(){}
private static NumberMachion numbermachion=newNumberMachion();
public static NumberMachion getNumberMachion(){
return numbermachion;
}
}
运行结果:
总结:因为想到有三种不同的号码,并且只有一个取号的机子,所以想到了一个号码管理器来管理这三种号码。并且把号码管理器定义成单例。因为有三种不同的固定窗口,所以想到了枚举。
通过银行调度系统是我更加明白了“谁拥有数据就把方法定义在谁身上”。
自我思考与总结:当接到项目是不应急于编写代码,代码是次要的,思想才是主要的。思想决定着代码的好坏、系统的优略。充分的认识项目的目的也是提到编码效率的手段。要充分的认识事物的本质。项目的主要用途也是我们考虑在内的的,有的用于网络视屏,这样的我们可以适当的降低安全性,而主要提高数据传输速度;有的用于银行,这样的系统我们就要着重的考虑系统的安全性。具体情况还需具体分析。