黑马程序员--银行业务调度系统

来源:互联网 发布:excel数据批量打印 编辑:程序博客网 时间:2024/06/07 16:44

-----------------------android培训java培训java学习型技术博客、期待与您交流! ----------------------

银行业务调度系统

(一)模拟实现银行业务调度系统逻辑,具体需求如下:

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

Ø         有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

Ø            异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户:普通客户:快速客户 =  163

Ø             客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时  间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

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

Ø            VIP6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业  务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

Ø           随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

Ø         不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

(二)项目需求分析:

(1)       有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。我们知道在银行办理业务时,需要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户,去模拟用户。

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

(3)       各类型客户在其对应窗口按顺序依次办理业务,准确地说,应该是窗口依次叫号。

各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

(三)代码设计:

1  号码管理器

privateList<Integer> queueNumbers = new ArrayList<Integer>();//(用子类实现父类中的接口更灵活)

       public synchronized IntegergenerateNewNumber(){//模拟客户来了,是一个线程

              queueNumbers.add(++lastNumber);//每次产生的号码进行存储

              return lastNumber;

       }

       public synchronized Integer fetchNumber(){//模拟窗口服务,要调用窗口号,是一个线程

              if(queueNumbers.size()>0){

                     return(Integer)queueNumbers.remove(0);//先加载进去先取出来

              }else{

                     return null; //防止空指向异常

              }

       }

友情提示:

1)一个是模拟客户,一个是模拟窗口按照客户的编号来解决客户的问题,所以这是两个

线程访问了相同的数据,所以用同步解决。

2)在对号码进行存储的时候,要使用子类实现接口,这样便于程序的扩展性,更加灵活

2,号码机器

privateNumberMachine(){}//构造函数私有化,不让外界创建对象

       privatestatic NumberMachine instance = new NumberMachine();//本类中创建一个实例

       publicstatic NumberMachine getInstance(){//提高公共的访问方式

              returninstance;//返回实例对象

       }

友情提示:号码机器在整个系统中只有一个,所以要使用单例进行设计

3,服务窗口(以普通窗口为例)

                private void commonService(){

                     String windowName = "" + number + "" + type + "窗口"; //显示window窗口名称     

                     System.out.println(windowName+ "开始获取普通任务!");

                     Integer serviceNumber =NumberMachine.getInstance().getCommonManager().fetchNumber();//获取到服务号       

                     if(serviceNumber != null){//判断服务号是否为空

                            System.out.println(windowName+ "开始为第" + serviceNumber + "号普通客户服务");//不为空开始服务     

                            Int maxRandom =Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;//最长服务时间与最短服务时间的间隔

                            int serviceTime =new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;//随机产生自定义的服务时间

                            try {//捕捉线程异常

                                   Thread.sleep(serviceTime);//休息时间

                            } catch(InterruptedException e) {

                                   e.printStackTrace();

                            }    

                            System.out.println(windowName+ "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "");         

                     }else{

                            System.out.println(windowName+ "没有取到普通任务,正在空闲一秒");         

                            try {

                                   Thread.sleep(1000);//窗口等待1秒钟

                            } catch(InterruptedException e) {

                                   e.printStackTrace();

                            }                         

                     }

                }

友情提示:

1)窗口只有三种且是固定的,那么这个时候我们可以使用枚举

2)对于窗口的加载我们可以使用switch语句(switch语句直接将固定的值加载进内存,

有利于提高效率)

3)对于常量,我们建议单独定义一个类进行定义;常量名的所有字母都是大写

4,客户获取自己的编号(以普通客户为例)

1)用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。

2)创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(//线程池中创建一个定时的线程,接收的是四个参数

                            newRunnable(){//第一个参数:执行的代码(任务)

                                   publicvoid run(){

                                          IntegerserviceNumber = NumberMachine.getInstance().

                                          getCommonManager().generateNewNumber();//获取生成的号码

                                          System.out.println("" + serviceNumber + "号普通客户正在等待服务!");                                    

                                   }

                            },

                            0,//第二个参数:过多长时间开始执行任务

                            Constants.COMMON_CUSTOMER_INTERVAL_TIME,//第三个参数:以后每隔多长时间又开始执行

                            TimeUnit.SECONDS);//给上面的参数赋值时间单位为秒

友情提示:

1)对于系统的代码设计,只有在不断的调试代码,才能不断完善。

2)对于银行的系统,这个我们相对而言是比较熟悉的,所以,从项目的需求、分析、设计、实现代码在到最后的测试,还算是比较容易一点的。其中,最重要的一点,感觉还是分析、设计相对比较难一点。

3)对于代码,如:条件的选择是使用if还是switch等语句等等,这些涉及到的都是比较细节的知识点,所以,Java基础扎实很重要。

4)对于代码的结构与优化,个人感觉还是比较重要的,这些就涉及到代码的重构与算法结构以及软件的架构,相对而言还是有一段比较长的时间路程要走。

5)比较交通灯管理系统和银行业务调度系统,重点还是在面向对象,虽然,之前学了面向对象,对它也挺熟悉的,但是,当需要在一个真正的项目需求中分析的时候,还是有点吃力,这样,要想精通面向对象(也是java的核心思想)还是需要不断的在项目中提高。

 

-----------------------android培训java培训java学习型技术博客、期待与您交流! ----------------------

 

原创粉丝点击