• 银行业务调度系统的业务需求


    1、银行业务调度系统的业务需求

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

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

    (3) 异步随机生成各种类型的客户,生成各类型用户的概率比例为:

            VIP客户 :普通客户 :快速客户 =  1 :6 :3。

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

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

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

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

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


    2、用面向对象的知识分析该业务调度系统。

    (1)有三种客户:普通客户,快速客户,VIP。

    (2)类图关系如下:




    代码实现:

    1、首先有一个号码生成器,即NumberManager类。

    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3.   
    4. public class NumberManager {  
    5.     private int lastNumber = 0;  
    6.     private List queueNumbers = new ArrayList();//定义一个集合装载生成的号码  
    7.       
    8.     public synchronized Integer generateNewNumber(){  
    9.         queueNumbers.add(++lastNumber);//不断生成号码  
    10.         return lastNumber;  
    11.     }  
    12.       
    13.     public synchronized Integer fetchNumber(){  
    14.         if(queueNumbers.size()>0){  
    15.             return (Integer)queueNumbers.remove(0);//排队取号,每次都取集合的第一个数值  
    16.         }else{  
    17.             return null;  
    18.         }  
    19.     }  
    20. }  
    2、由于有三种客户,因而需要三种号码生成器,因此用一个号码机器管理三种号码的生成,即NumberMachine类。
    1. public class NumberMachine {  
    2.       
    3.     private NumberMachine(){}//定义为私有构造方法  
    4.     private static NumberMachine instance = new NumberMachine();//实例化NumberMachine对象  
    5.     public static NumberMachine getInstance(){  
    6.         return instance;//返回对象  
    7.     }  
    8.       
    9.     private NumberManager commonManager = new NumberManager();//获得普通号码生成  
    10.     private NumberManager expressManager = new NumberManager();//获得快速号码生成  
    11.     private NumberManager vipManager = new NumberManager();//获得VIP号码生成  
    12.     public NumberManager getCommonManager() {  
    13.         return commonManager;  
    14.     }  
    15.     public NumberManager getExpressManager() {  
    16.         return expressManager;  
    17.     }  
    18.     public NumberManager getVipManager() {  
    19.         return vipManager;  
    20.     }  
    21.       
    22. }  

    3、准备好了号码的生成和号码机器的管理,接下来编写服务窗口类,ServiceWindow类。
    1. import java.util.Random;  
    2. import java.util.concurrent.Executors;  
    3. import java.util.logging.Logger;  
    4.   
    5. /** 
    6.  * 没有把VIP窗口和快速窗口做成子类,是因为实际业务中的普通窗口可以随时被设置为VIP窗口和快速窗口。 
    7.  * */  
    8. public class ServiceWindow {  
    9.     private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");  
    10.     private CustomerType type = CustomerType.COMMON;//默认情况下,为普通客户。  
    11.     private int number = 1;//窗口号  
    12.   
    13.     public CustomerType getType() {  
    14.         return type;  
    15.     }  
    16.   
    17.     public void setType(CustomerType type) {  
    18.         this.type = type;  
    19.     }  
    20.       
    21.     public void setNumber(int number){  
    22.         this.number = number;  
    23.     }  
    24.       
    25.     public void start(){  
    26.         Executors.newSingleThreadExecutor().execute(  
    27.                 new Runnable(){  
    28.                     public void run(){  
    29.                         //下面这种写法的运行效率低,最好是把while放在case下面  
    30.                         while(true){  
    31.                             switch(type){  
    32.                                 case COMMON:  
    33.                                     commonService();  
    34.                                     break;  
    35.                                 case EXPRESS:  
    36.                                     expressService();  
    37.                                     break;  
    38.                                 case VIP:  
    39.                                     vipService();  
    40.                                     break;  
    41.                             }  
    42.                         }  
    43.                     }  
    44.                 }  
    45.         );  
    46.     }  
    47.       
    48.     private void commonService(){  
    49.         String windowName = "第" + number + "号" + type + "窗口";         
    50.         System.out.println(windowName + "开始获取普通任务!");  
    51.         Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();         
    52.         if(serviceNumber != null ){  
    53.             System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");          
    54.             int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;  
    55.             int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;  
    56.       
    57.             try {  
    58.                 Thread.sleep(serviceTime);  
    59.             } catch (InterruptedException e) {  
    60.                 e.printStackTrace();  
    61.             }     
    62.             System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");        
    63.         }else{  
    64.             System.out.println(windowName + "没有取到普通任务,正在空闲一秒");       
    65.             try {  
    66.                 Thread.sleep(1000);  
    67.             } catch (InterruptedException e) {  
    68.                 e.printStackTrace();  
    69.             }                 
    70.         }  
    71.     }  
    72.       
    73.     private void expressService(){  
    74.         Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();  
    75.         String windowName = "第" + number + "号" + type + "窗口";     
    76.         System.out.println(windowName + "开始获取快速任务!");         
    77.         if(serviceNumber !=null){  
    78.             System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务");              
    79.             int serviceTime = Constants.MIN_SERVICE_TIME;  
    80.             try {  
    81.                 Thread.sleep(serviceTime);  
    82.             } catch (InterruptedException e) {  
    83.                 e.printStackTrace();  
    84.             }         
    85.             System.out.println(windowName + "完成为第" + serviceNumber + "号快速客户服务,总共耗时" + serviceTime/1000 + "秒");        
    86.         }else{  
    87.             System.out.println(windowName + "没有取到快速任务!");                 
    88.             commonService();  
    89.         }  
    90.     }  
    91.       
    92.     private void vipService(){  
    93.   
    94.         Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();  
    95.         String windowName = "第" + number + "号" + type + "窗口";     
    96.         System.out.println(windowName + "开始获取VIP任务!");            
    97.         if(serviceNumber !=null){  
    98.             System.out.println(windowName + "开始为第" + serviceNumber + "号VIP客户服务");             
    99.             int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;  
    100.             int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;  
    101.             try {  
    102.                 Thread.sleep(serviceTime);  
    103.             } catch (InterruptedException e) {  
    104.                 e.printStackTrace();  
    105.             }         
    106.             System.out.println(windowName + "完成为第" + serviceNumber + "号VIP客户服务,总共耗时" + serviceTime/1000 + "秒");       
    107.         }else{  
    108.             System.out.println(windowName + "没有取到VIP任务!");                
    109.             commonService();  
    110.         }     
    111.     }  
    112. }  

    4、在窗口服务类中,调用了一个枚举类CustomerType。
    1. public enum CustomerType {  
    2.     COMMON,EXPRESS,VIP;  
    3.     public String toString(){  
    4.         String name = null;  
    5.         switch(this){  
    6.         case COMMON:  
    7.             name = "普通";  
    8.             break;  
    9.         case EXPRESS:  
    10.             name = "快速";  
    11.             break;  
    12.         case VIP:  
    13.             name = name();  
    14.             break;  
    15.         }  
    16.         return name;  
    17.     }  
    18. }  

    5、完成了这些,该编写主类了MainClass。
    1. import java.util.concurrent.Executors;  
    2. import java.util.concurrent.TimeUnit;  
    3. import java.util.logging.Logger;  
    4.   
    5. public class MainClass {  
    6.       
    7.     private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");  
    8.       
    9.   
    10.     public static void main(String[] args) {  
    11.         //产生4个普通窗口  
    12.         for(int i=1;i<5;i++){  
    13.             ServiceWindow window =  new ServiceWindow();  
    14.             window.setNumber(i);  
    15.             window.start();  
    16.         }  
    17.       
    18.         //产生1个快速窗口  
    19.         ServiceWindow expressWindow =  new ServiceWindow();  
    20.         expressWindow.setType(CustomerType.EXPRESS);  
    21.         expressWindow.start();  
    22.           
    23.         //产生1个VIP窗口       
    24.         ServiceWindow vipWindow =  new ServiceWindow();  
    25.         vipWindow.setType(CustomerType.VIP);  
    26.         vipWindow.start();        
    27.           
    28.         //普通客户拿号  
    29.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
    30.                 new Runnable(){  
    31.                     public void run(){  
    32.                         Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();  
    33.                         /** 
    34.                          * 采用logger方式,无法看到直观的运行效果,因为logger.log方法内部并不是直接把内容打印出出来, 
    35.                          * 而是交给内部的一个线程去处理,所以,打印出来的结果在时间顺序上看起来很混乱。 
    36.                          */  
    37.                         //logger.info("第" + serviceNumber + "号普通客户正在等待服务!");  
    38.                         System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");                         
    39.                     }  
    40.                 },  
    41.                 0,  
    42.                 Constants.COMMON_CUSTOMER_INTERVAL_TIME,   
    43.                 TimeUnit.SECONDS);  
    44.           
    45.         //快速客户拿号  
    46.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
    47.                 new Runnable(){  
    48.                     public void run(){  
    49.                         Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();  
    50.                         System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");  
    51.                     }  
    52.                 },  
    53.                 0,  
    54.                 Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,   
    55.                 TimeUnit.SECONDS);  
    56.           
    57.         //VIP客户拿号  
    58.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
    59.                 new Runnable(){  
    60.                     public void run(){  
    61.                         Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();  
    62.                         System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");  
    63.                     }  
    64.                 },  
    65.                 0,  
    66.                 Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,   
    67.                 TimeUnit.SECONDS);  
    68.     }  
    69.   
    70. }  

    6、编程习惯是,将常量全部放在一个单独的类中,这样便于程序的修改和重用。Constants类。
    1. public class Constants {  
    2.     public static int MAX_SERVICE_TIME = 10000//10绉掞紒  
    3.     public static int MIN_SERVICE_TIME = 1000//1绉掞紒  
    4.       
    5.     public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;      
    6. }  


    总结一下:从上述的学习中,了解了银行业务调度系统的大致流程。懂得了如何分析一个业务系统,要善于利用面向对象知识。在学习的时候,要细心,认真,要有耐心。程序不可能一次性成功,需要不断的去调试,去优化。

  • 相关阅读:
    angularjs 过滤器
    angularjs 工具方法
    angularjs 模块化
    angularjs ng-app
    angularjs作用域和函数调用
    Android sdk版本以及兼容性问题
    跟谁鼠标移动
    事件捕获,事件冒泡,事件取消
    netsh 转发 5000 端口到 80端口的命令和删除方法
    [微软官网]windows server 内存限制
  • 原文地址:https://www.cnblogs.com/guwenren/p/3008927.html
Copyright © 2020-2023  润新知