黑马程序员--java项目之银行业务调度系统

一、 银行业务调度系统项目需求 

   

二、面向对象的分析与设计

     1、有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务 。每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,需要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。由于有三类客户,每类客户的号码编排都是完全独立的,所以,本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。代码如下:
//定义一个生成号码的类
public class NumberManager {
    private int lastNumber = 1;
    //该容器用来接收客户号码
    List<Integer> queue = new ArrayList<Integer>();
    
    //生成号码的方法,将号码存入集合中保存,需要线程安全
    public synchronized Integer generateNewManager(){
        queue.add(lastNumber);
        return lastNumber++;
    }
    
    //窗口取号的方法,移除掉集合中第一位,需要线程安全
    public synchronized Integer fetchServiceNumber(){
        if(queue.size() > 0){
            return (Integer)queue.remove(0);
        }else{
            return null;
        }
    }
} 

//定义一个号码管理机器,将不同客户的号码放到同一个机器中
public class NumberMachine {
    //三种类型的客户
    private NumberManager commonManager = new NumberManager();
    private NumberManager expressManager = new NumberManager();
    private NumberManager vipManager = new NumberManager();
    
    //提供获取不同客户的方法
    public NumberManager getCommonManager() {
        return commonManager;
    }
    public NumberManager getExpressManager() {
        return expressManager;
    }
    public NumberManager getVipManager() {
        return vipManager;
    }
    
    //单例设计模式,只生成一台机器
    private static NumberMachine numberMachine = new NumberMachine();
    public static NumberMachine getInstence(){
        return numberMachine;
    }
} 
    2、各类型客户在其对应窗口按顺序依次办理业务 ,根据面向对象设计分析,这里应该把窗口作为对象,不同的窗口提供不同的服务。
至于各个窗口该叫哪一个号,它应该去问相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。代码如下:
public class ServiceWindow {
    //先获取机器的对象,从机器中获取号码 
    NumberMachine numberMachine = NumberMachine.getInstence();
     
     //客户类型只有三种固定类型,所以定义在类中作为常量,默认普通
     private CostomerType type = CostomerType.COMMON;
     //窗口的ID,默认为1,提供set方法改变这个值
     private int windowId = 1;
     public void setType(CostomerType type) {
         this.type = type;
     }
     public void setWindowId(int windowId) {
         this.windowId = windowId;
     }
     
     //开始服务
     public void start(){
         //放到线程池中执行
         Executors.newSingleThreadExecutor().execute(new Runnable(){
            public void run() {
                //不断的获取号码
                while(true){
                    //判断客户类型,办理相应的业务
                    switch(type){
                        case COMMON:
                            commonService();
                            break;
                        case EXPRESS:
                            expressService();
                            break;
                        case VIP:
                            vipService();
                            break;
                    }         
                }
            }
         });
     }
     
     //普通窗口的服务
     private void commonService() {
         //窗口名
         String windowName = "第"+ windowId+"号"+type+"窗口";
         System.out.println(windowName + "正在获取任务");
         //获取普通客户
         Integer number = numberMachine.getCommonManager().fetchServiceNumber();
         if(number != null){
             //办理业务
             long beginTime = System.currentTimeMillis();                 
             //随机生成办理客户业务需要花费的时间,办理业务花费时间的最大值和最小值作为常亮定义在Contants类中
             int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
             int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME;
             try {
                 Thread.sleep(serveTime);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             long costTime = System.currentTimeMillis() - beginTime;
             System.out.println(windowName + "正在为第"+ number+ "位普通客户服务,耗时" + costTime/1000 + "秒");
                 
         //如果没有客户,休息1秒再叫号。
         }else{
             System.out.println(windowName + "没有取到任务,休息一下");
             try {     
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }    
     }
     
     //快速窗口服务
     private void expressService() {
         String windowName = "第"+ windowId+"号快速窗口";
         System.out.println(windowName + "正在获取任务");
         Integer number = numberMachine.getExpressManager().fetchServiceNumber();
         if(number != null){
             long beginTime = System.currentTimeMillis();
             try {
                //项目需要快速窗口办理业务所需时间为最小值。
                 Thread.sleep(Constants.MIN_SERVICE_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
             long serveTime = System.currentTimeMillis() - beginTime;
             System.out.println(windowName + "正在为第"+ number+ "位快速客户服务,耗时" + serveTime/1000 + "秒");
                 
         }else{
             System.out.println(windowName + "没有取到任务,开始办理普通客户");
             //没有快速客户时办理普通窗口的业务
             commonService();
         }    
     }

     //vip窗口服务
     private void vipService() {
         String windowName = "第"+ windowId+"号VIP窗口";
         System.out.println(windowName + "正在获取任务");
         Integer number = numberMachine.getVipManager().fetchServiceNumber();
         if(number != null){
             long beginTime = System.currentTimeMillis();                 
             int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
             int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME;
             try {
                 Thread.sleep(serveTime);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             long costTime = System.currentTimeMillis() - beginTime;
             System.out.println(windowName + "正在为第"+ number+ "位VIP客户服务,耗时" + costTime/1000 + "秒");
                 
         }else{
             System.out.println(windowName + "没有取到任务,开始办理普通客户");
             //没有Vip客户时办理普通客户业务
             commonService();
         }    
     }
}

 3、代码中需要用到的一些常亮类

//客户类型
public enum CostomerType {
    COMMON,EXPRESS,VIP;
    //为了在控制台获取类型的名字,重写toString方法
    public String toString(){
        switch(this){
            case COMMON:
                return "普通";
            case EXPRESS:
                return "快速";
            case VIP:
                return name();
        }
        return null;
    }
}

//项目中用到的所有常亮
public class Constants {
    //客户办理业务花费的最大值10秒和最小值1秒
    public static int MAX_SERVICE_TIME = 10000;
    public static int MIN_SERVICE_TIME = 1000;
    //生成一个普通客户的时间间隔
    public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}

 4、创建主类生成窗口和客户

 

//主类,生成服务窗口,并模拟产生客户
public class MainClass {
    public static void main(String[] args) {
        //生成四个普通窗口并开始服务
        for (int i = 1; i < 5; i++) {
            ServiceWindow commonWindow = new ServiceWindow();
            commonWindow.setWindowId(i);
            commonWindow.start();
        }
        
        //生成一个快速窗口
        ServiceWindow expressWindow = new ServiceWindow();
        expressWindow.setType(CostomerType.EXPRESS);
        expressWindow.start();
        
        //生成一个VIP窗口
        ServiceWindow vipWindow = new ServiceWindow();
        vipWindow.setType(CostomerType.VIP);
        vipWindow.start();
        
        //模拟生成普通客户
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run() {
                        Integer number = NumberMachine.getInstence().getCommonManager().generateNewManager();
                        System.out.println("第"+number+"号普通客户等待服务");
                    }
                }, 
                0, 
                Constants.COMMON_CUSTOMER_INTERVAL_TIME, 
                TimeUnit.SECONDS);
        
        //模拟生成快速客户
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run() {
                        Integer number = NumberMachine.getInstence().getExpressManager().generateNewManager();
                        System.out.println("第"+number+"号快速客户等待服务");
                    }
                }, 
                0,
                Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, 
                TimeUnit.SECONDS);        
    
        //模拟生成VIP客户
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
                new Runnable(){
                    public void run() {
                        Integer number = NumberMachine.getInstence().getVipManager().generateNewManager();
                        System.out.println("第"+number+"号VIP客户等待服务");
                    }
                }, 
                0, 
                Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, 
                TimeUnit.SECONDS);    
    }
} 
 

 

 

posted @ 2013-04-13 15:15  郭彦君  阅读(375)  评论(0编辑  收藏  举报