银行业务调度系统
1、
模拟实现银行业务调度系统逻辑,具体需求如下:
Ø 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
Ø 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
Ø 异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
Ø 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
Ø 各类型客户在其对应窗口按顺序依次办理业务。
Ø 当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
Ø 随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
package com.heima.jianjian;
import java.util.ArrayList;
import java.util.List;
2、
l有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务 。
Ø知道每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,我想到要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。
Ø由于有三类客户,每类客户的号码编排都是完全独立的,所以,我想到本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。
l各类型客户在其对应窗口按顺序依次办理业务 ,准确地说,应该是窗口依次叫号。
Ø各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。
Ø如果我不是多次亲身经历银行的这种业务,再加之积累了大量面向对象的应用开发经验,我也不知道能否轻松进行这种设计,能否发掘出其中隐含的对象信息。
3.
lNumberManager类
Ø定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。
Ø定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步。
lNumberMachine类
Ø定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。
Ø将NumberMachine类设计成单例。
4.
package com.heima.jianjian;
import java.util.ArrayList;
import java.util.List;
/*
* 面向对象就一定要知道自己的这个类到底要实现怎样的功能,这个号码管理器的功能
* 一是产生新客户号码,取出等待客户好吗,其中的细节都要考虑到
* 开始写第一个对象:NumberManager
定义一个用于存储上一个客户号码的成员变量,和用于存储所有等待服务的客户好吗的队列集合
定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据
所以要进行同步,要用关键字满足现成的互斥*/
public class NumberManager
{
private int lastNumber = 1;
private List<Integer>lineQueueNumber =new ArrayList<Integer>();
//编写生成新号码的方法,注意运算符的使用
public int generateNewNumber()
{
lineQueueNumber.add(lastNumber);
return lastNumber ++;
}
//编写窗口要服务的号码方法,生成了这么多号码,但是服务的速度可跟不上生成的服务啊,这个要考虑到
public int fetchServiceNumber()
{
return lineQueueNumber.remove(0);//拿走服务号,一举两得
}
}
但是,区号和生成号都对同一个变量lineQueueNumber做出了访问,这就相当于两个线程对同一个变量的访问,为了产生互斥效果,需要加入关键字synchronized
public synchronized int generateNewNumber()
{
lineQueueNumber.add(lastNumber);
return lastNumber ++;
}
//编写窗口要服务的号码方法,生成了这么多号码,但是服务的速度可跟不上生成的服务啊,这个要考虑到
public synchronized intfetchServiceNumber()
{
return lineQueueNumber.remove(0);//拿走服务号,一举两得
}
11.
看一下NumberMerchine代码
package com.heima.jianjian;
public class NumberMerchine
{
private NumberManagercommonClient =new NumberManager();
private NumberManagerfastClient =new NumberManager();
private NumberManagerVIPClient =new NumberManager();
//生成get方法;
public NumberManager getCommonClient()
{
return commonClient;
}
public NumberManager getFastClient()
{
return fastClient;
}
public NumberManager getVIPClient()
{
return VIPClient;
}
//把这个类设计成单列模式
private NumberMerchine(){}
private static NumberMerchine singleMerchine =new NumberMerchine();
public static NumberMerchinegetMerchineInstance()
{
returnsingleMerchine;
}
}
3.服务窗口类写完后,感觉要了自己半条命,我觉得其中涉及到太多的知识点了,首先是方法的重构refector,记住,抽取方法的时候Extract Method ,会让你选择抽出方法后的位置,destination ,有可能是内部类中,所以选择外部类或者内部类吧;
三种类型的窗口,应该使用代码重用,只有部分不同,这个稍后写一下吧
package com.heima.jianjian;
//这个类应该有两个属性,是机号窗口,是什么类型的窗口,当然可以用构造方法来实现
//但是更好的做法是生成set方法,这样这个窗口就不是一生成就是用眼都是某种窗口,而是通过
//它传递的参数来决定它是一个怎样的窗口
import java.util.Random;
import java.util.concurrent.Executors;
/*定义银行窗口类,来执行服务的操作
使用线程来做,
Executors.newSingleTreadExecutor
把任务交给线程池,线程池再从池中找一个空闲的线程来做*/
public class ServiceWindow
{
private WindowTypewindowType = WindowType.COMMON;
private int windowNum = 1;
public void setWindowType(WindowType windowType)
{
this.windowType = windowType;
}
public void setWindowNum(int windowNum)
{
this.windowNum = windowNum;
}
public void start()
{// 新建一个单一线程池,执行单一线程,用来取某一种窗口的号码,注意是不停的取号
Executors.newSingleThreadExecutor().execute(new Runnable()
{
@Override
public void run()
{
while (true)
{
switch (windowType)
{
caseCOMMON:
commonService();
break;
caseFAST:
fastService();//快速窗口和vip窗口在没有接到服务的时候,不会休息而是去接受普通服务
//所以要再次调用commonService方法!
break;
caseVIP:
vipService();
break;
}
}
}
});
}
private void commonService()
{
// 如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
Integer clientNum = NumberMerchine.getMerchineInstance()
.getCommonClient().fetchServiceNumber();
System.out.println(windowNum +"号" +windowType + "正在等待服务;");
if (clientNum ==null)
// 注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
// 如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum +"号" +windowType + "未接受到服务");
// 如果为空的上面的情况,如果不为空的话,开始服务
// 知识模拟服务的休息时间,随机的
else
{
// 花费时间costTime
long begainTime = System.currentTimeMillis();
// 服务时间1到6秒
long serviceTime = (long)new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch (InterruptedException e)
{
// TODO Auto-generatedcatch block
e.printStackTrace();
}
long cosTimet = System.currentTimeMillis() -begainTime;
System.out.println(windowNum +windowType.toString() +"为"
+ clientNum + "号普通客户服务完毕,共耗时" + cosTimet / 1000 +"秒");
}
// 没有取到服务,还有服务完毕后,还是要继续服务的,休息一秒中后,继续服务
try
{
System.out.println(windowNum +windowType.toString() +"继续等待服务");
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
private void fastService()
{
// 如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
Integer clientNum = NumberMerchine.getMerchineInstance()
.getFastClient().fetchServiceNumber();
System.out.println(windowNum +"号" +windowType + "正在等待服务;");
//未接受到fast或者vip服务就应该转向普通服务;
if (clientNum ==null)
{
// 注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
// 如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum +"号" +windowType + "无专业服务,开始为普通客户服务");
commonService();
}
// 如果为空的上面的情况,如果不为空的话,开始服务
// 知识模拟服务的休息时间,随机的
else
{
// 花费时间costTime
long begainTime = System.currentTimeMillis();
// 服务时间1到6秒
long serviceTime = (long)new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch (InterruptedException e)
{
// TODO Auto-generatedcatch block
e.printStackTrace();
}
long cosTimet = System.currentTimeMillis() -begainTime;
System.out.println(windowNum +windowType.toString() +"为"
+ clientNum + "号快速客户服务完毕,共耗时" + cosTimet / 1000 +"秒");
}
// 没有取到服务,还有服务完毕后,还是要继续服务的,休息一秒中后,继续服务
}
private void vipService()
{
// 如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
Integer clientNum = NumberMerchine.getMerchineInstance().getVIPClient()
.fetchServiceNumber();
System.out.println(windowNum +"号" +windowType + "正在等待服务;");
if (clientNum ==null)
{
// 注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
// 如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum +"号" +windowType + "无专业服务,开始为普通客户服务");
commonService();
}
else
{
// 花费时间costTime
long begainTime = System.currentTimeMillis();
// 服务时间1到6秒
long serviceTime = (long)new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch (InterruptedException e)
{
// TODO Auto-generatedcatch block
e.printStackTrace();
}
long cosTimet = System.currentTimeMillis() -begainTime;
System.out.println(windowNum +windowType.toString() +"为"
+ clientNum + "号VIP客户服务完毕,共耗时" + cosTimet / 1000+"秒");
}
// 没有取到服务,还有服务完毕后,还是要继续服务的,特殊窗口不需要休息
}
}
4.
我觉得,总的逻辑是要在main方法中体现的,那么在这个银行业务调度系统中,main方法要做的事情是什么呢,我们来将以前的类的功能来分析一下:
NumberManager类:号码管理器,用来生成来获取服务的新的客户,其中有生成号码的方法,和拿走服务客户的方法;小技巧是使用remove类似队列,先到先服务;
NumberMerchine类:来服务的人需要一个机器为他们来分类,当然设计成单列模式,是因为只需要一个机器来管理这三个对象,含有这三个号码管理器对象的实例以及获取实的方法
WindowService类:具体实现各窗口的服务,那么各窗口要完成什么服务,在这个类中要有体现,这是要对面向对象程序设计的理解啊:两个属性,窗口的类型;窗口的编号;方法一个执行过程start,执行一个线程,根据窗口类型,接受编号,获取服务
常量类和枚举:一个不大不小的工程,涉及了多少变量或者常量,为了方便查询和修改,一个必要的常量类是应该设计的;比如说服务时间,固定常量;
package com.heima.jianjian;
public class VariableCollection
{
public static final int COMMOM_ACCESS_TIME_RATE = 1;
public static final int FAST_ACCESS_TIME_RATE = 3;
public static final int VIP_ACCESS_TIME_RATE = 6;
}
public class MainTest
{
public static void main(String[] args)
{
for (int i = 1; i < 4; i++)//四个普通窗口,一个VIP,一个fast
{
ServiceWindow commonWindow = new ServiceWindow();
int num = i;
commonWindow.setWindowNum(num);
commonWindow.setWindowType(WindowType.COMMON);
commonWindow.start();
}
ServiceWindow fastWindow = new ServiceWindow();
fastWindow.setWindowNum(5);
fastWindow.setWindowType(WindowType.FAST);
fastWindow.start();
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setWindowNum(6);
vipWindow.setWindowType(WindowType.VIP);
vipWindow.start();
// 单一的循环线程池,执行固定的循环频率
// 只是做到现在,我还是没有生成号码,一会我再拉分析整个main方法的过程
// 生成号码是一个循环的过程,又用到了并发的Executor了
//分别写三个线程池,只有访问时间的不同
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Runnable()
{
@Override
public void run()
{
// TODO Auto-generatedmethod stub
}
}, 0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.COMMOM_ACCESS_TIME_RATE , TimeUnit.SECONDS);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Runnable()
{
@Override
public void run()
{
// TODO Auto-generatedmethod stub
}
}, 0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.FAST_ACCESS_TIME_RATE, TimeUnit.SECONDS);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
new Runnable()
{
@Override
public void run()
{
// TODO Auto-generatedmethod stub
}
}, 0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.VIP_ACCESS_TIME_RATE , TimeUnit.SECONDS);
}
看一下完整的代码:
package com.heima.jianjian;
import java.util.ArrayList;
import java.util.List;
/*
* 面向对象就一定要知道自己的这个类到底要实现怎样的功能,这个号码管理器的功能
* 一是产生新客户号码,取出等待客户好吗,其中的细节都要考虑到
* 开始写第一个对象:NumberManager
定义一个用于存储上一个客户号码的成员变量,和用于存储所有等待服务的客户好吗的队列集合
定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据
所以要进行同步,要用关键字满足现成的互斥*/
public class NumberManager
{
privateint lastNumber = 1;
//用一个集合储存等候人员
privateList<Integer> lineQueueNumber = new ArrayList<Integer>();
//编写生成新号码的方法,注意运算符的使用
publicsynchronized Integer generateNewNumber()
{
lineQueueNumber.add(lastNumber);
returnlastNumber ++;
}
//编写窗口要服务的号码方法,生成了这么多号码,但是服务的速度可跟不上生成的服务啊,这个要考虑到
public synchronized IntegerfetchServiceNumber()
{
Integer Null = null;
if(lineQueueNumber.size() > 0)
return lineQueueNumber.remove(0);//拿走服务号,一举两得
else
return Null;
}
}
package com.heima.jianjian;
public class NumberMerchine
{
private NumberManagercommonClient =new NumberManager();
private NumberManagerfastClient =new NumberManager();
private NumberManagerVIPClient =new NumberManager();
//生成get方法;
public NumberManager getCommonClient()
{
return commonClient;
}
public NumberManager getFastClient()
{
return fastClient;
}
public NumberManager getVIPClient()
{
return VIPClient;
}
//把这个类设计成单列模式
private NumberMerchine(){}
private static NumberMerchine singleMerchine =new NumberMerchine();
public static NumberMerchine getMerchineInstance()
{
return singleMerchine;
}
}
package com.heima.jianjian;
//这个类应该有两个属性,是机号窗口,是什么类型的窗口,当然可以用构造方法来实现
//但是更好的做法是生成set方法,这样这个窗口就不是一生成就是用眼都是某种窗口,而是通过
//它传递的参数来决定它是一个怎样的窗口
import java.util.Random;
import java.util.concurrent.Executors;
/*定义银行窗口类,来执行服务的操作
使用线程来做,
Executors.newSingleTreadExecutor
把任务交给线程池,线程池再从池中找一个空闲的线程来做*/
public class ServiceWindow
{
privateWindowType windowType = WindowType.COMMON;
privateint windowNum = 1;
publicvoid setWindowType(WindowType windowType)
{
this.windowType= windowType;
}
publicvoid setWindowNum(int windowNum)
{
this.windowNum= windowNum;
}
publicvoid start()
{// 新建一个单一线程池,执行单一线程,用来取某一种窗口的号码,注意是不停的取号
Executors.newSingleThreadExecutor().execute(newRunnable()
{
@Override
publicvoid run()
{
while(true)
{
switch(windowType)
{
caseCOMMON:
commonService();
break;
caseFAST:
fastService();//快速窗口和vip窗口在没有接到服务的时候,不会休息而是去接受普通服务
//所以要再次调用commonService方法!
break;
caseVIP:
vipService();
break;
}
}
}
});
}
privatevoid commonService()
{
//如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
IntegerclientNum = NumberMerchine.getMerchineInstance()
.getCommonClient().fetchServiceNumber();
System.out.println(windowNum+ "号" +windowType + "正在等待服务;");
if(clientNum == null)
//注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
//如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum+ "号" +windowType + "未接受到服务");
//如果为空的上面的情况,如果不为空的话,开始服务
//知识模拟服务的休息时间,随机的
else
{
//花费时间costTime
longbegainTime = System.currentTimeMillis();
//服务时间1到6秒
longserviceTime = (long) new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch(InterruptedException e)
{
//TODO Auto-generated catch block
e.printStackTrace();
}
longcosTimet = System.currentTimeMillis() - begainTime;
System.out.println(windowNum+ windowType.toString() + "为"
+clientNum + "号普通客户服务完毕,共耗时" + cosTimet / 1000 + "秒");
}
//没有取到服务,还有服务完毕后,还是要继续服务的,休息一秒中后,继续服务
try
{
System.out.println(windowNum+ windowType.toString() + "继续等待服务");
Thread.sleep(1000);
}
catch(InterruptedException e)
{
//TODO Auto-generated catch block
e.printStackTrace();
}
}
privatevoid fastService()
{
//如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
IntegerclientNum = NumberMerchine.getMerchineInstance()
.getFastClient().fetchServiceNumber();
System.out.println(windowNum+ "号" +windowType + "正在等待服务;");
//未接受到fast或者vip服务就应该转向普通服务;
if(clientNum == null)
{
//注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
//如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum+ "号" +windowType + "无专业服务,开始为普通客户服务");
commonService();
}
//如果为空的上面的情况,如果不为空的话,开始服务
//知识模拟服务的休息时间,随机的
else
{
//花费时间costTime
longbegainTime = System.currentTimeMillis();
//服务时间1到6秒
longserviceTime = (long) new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch(InterruptedException e)
{
//TODO Auto-generated catch block
e.printStackTrace();
}
longcosTimet = System.currentTimeMillis() - begainTime;
System.out.println(windowNum+ windowType.toString() + "为"
+clientNum + "号快速客户服务完毕,共耗时" + cosTimet / 1000 + "秒");
}
//没有取到服务,还有服务完毕后,还是要继续服务的,休息一秒中后,继续服务
}
privatevoid vipService()
{
//如果是普通客户窗口的话,请打印该窗口正在等待服务的信息,其他两个相同
IntegerclientNum = NumberMerchine.getMerchineInstance().getVIPClient()
.fetchServiceNumber();
System.out.println(windowNum+ "号" +windowType + "正在等待服务;");
if(clientNum == null)
{
//注意了,remove有可能返回的是null,也有可能是数字,所以你的返回值最好定义为Integer,回去改一改
//如果为null的话,说明此时没有取到服务,请打印该窗口未接收到服务
System.out.println(windowNum+ "号" +windowType + "无专业服务,开始为普通客户服务");
commonService();
}
else
{
//花费时间costTime
longbegainTime = System.currentTimeMillis();
//服务时间1到6秒
longserviceTime = (long) new Random().nextInt(5000) + 1001;
try
{
Thread.sleep(serviceTime);
}
catch(InterruptedException e)
{
//TODO Auto-generated catch block
e.printStackTrace();
}
longcosTimet = System.currentTimeMillis() - begainTime;
System.out.println(windowNum+ windowType.toString() + "为"
+clientNum + "号VIP客户服务完毕,共耗时" + cosTimet / 1000 +"秒");
}
//没有取到服务,还有服务完毕后,还是要继续服务的,特殊窗口不需要休息
}
}
package com.heima.jianjian;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainTest
{
publicstatic void main(String[] args)
{
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
newRunnable()
{
@Override
publicvoid run()
{//声称普通客户
NumberMerchine.getMerchineInstance().getCommonClient().generateNewNumber();
}
},0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.COMMOM_ACCESS_TIME_RATE, TimeUnit.SECONDS);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
newRunnable()
{
@Override
publicvoid run()
{
NumberMerchine.getMerchineInstance().getFastClient().generateNewNumber();
}
},0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.FAST_ACCESS_TIME_RATE,TimeUnit.SECONDS);
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
newRunnable()
{
@Override
publicvoid run()
{
NumberMerchine.getMerchineInstance().getVIPClient().generateNewNumber();
}
},0,// (多长时间后执行这个线程)我们来写一个常量类,来实现比例1:3:6,对应vip,fast,common
VariableCollection.VIP_ACCESS_TIME_RATE ,TimeUnit.SECONDS);
for(int i = 1; i < 4; i++)// 四个普通窗口,一个VIP,一个fast
{
ServiceWindowcommonWindow = new ServiceWindow();
intnum = i;
commonWindow.setWindowNum(num);
commonWindow.setWindowType(WindowType.COMMON);
commonWindow.start();
}
ServiceWindowfastWindow = new ServiceWindow();
fastWindow.setWindowNum(5);
fastWindow.setWindowType(WindowType.FAST);
fastWindow.start();
ServiceWindowvipWindow = new ServiceWindow();
vipWindow.setWindowNum(6);
vipWindow.setWindowType(WindowType.VIP);
vipWindow.start();
//单一的循环线程池,执行固定的循环频率
//只是做到现在,我还是没有生成号码,一会我再拉分析整个main方法的过程
//生成号码是一个循环的过程,又用到了并发的Executor了
//分别写三个线程池,只有访问时间的不同
}
}
package com.heima.jianjian;
//枚举类型,用来存放三种窗口类型
public enum WindowType
{
COMMON, FAST,VIP;
// 重写toSting方法让他返回当前类型的字符串
public String toString()
{
switch(this)
{
case COMMON:
return "普通窗口";
case FAST:
return "快速窗口";
case VIP:
return this.name()+"窗口";//当前对象的名字
}
return null;
}
}
package com.heima.jianjian;
public class VariableCollection
{
public static final int COMMOM_ACCESS_TIME_RATE = 1;
public static final int FAST_ACCESS_TIME_RATE = 3;
public static final int VIP_ACCESS_TIME_RATE = 6;
}