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

来源:互联网 发布:淘宝退货售后卡怎么写 编辑:程序博客网 时间:2024/05/21 09:17

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

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客户,普通客户,快速客户;异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。

         (1) 首先,经常在银行办理业务的人更有利于理解本系统。每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的,所以,我们想要有一个号码管理器对象,让这个对象不断的产生号码,就等于随机生成了客户;

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

2、各类型客户在其对应窗口按顺序依次办理业务,准确的说,应该是窗口依次叫号;

        (1)、各个窗口怎么知道该叫那一个号了呢?它一定是问的对应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码;

        (2)、如果不是多次亲身经历银行的这种业务,再加上积累大量的面向对象开发的应用经验,不可能轻松的进行这种设计,能否发掘出其中隐含的对象信息,还要看日积月累出来的感觉。

类图进行分析:

 

                          

编码如下


1、号码管理器类(NumberManager类

定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。
定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步。

import java.util.ArrayList;import java.util.List;/** * NumberManager:号码管理器(可理解为银行挂号机器中的一个分支) * 当客户来了要生成一个号码,并加在对应客户类型的集合中; * 服务窗口会找对应的取号机取号去服务。 * 因为生成号码和取走号码同时用到成员变量,但又是不同的线程,需要加同步 */publicclass NumberManager{       privateintlastNumber = 1;    //记住上一个号码       private List<Integer> queueNumber = new ArrayList<Integer>();             //客户来了生成号码       publicsynchronized Integer generateNewManager()       {              //来一个客户就往集合中加一个号码              queueNumber.add(lastNumber);                returnlastNumber++;         }             //服务窗口获取号码       publicsynchronized Integer fetchServiceNumber()       {              Integer number = null;              if(queueNumber.size()>0)              {                     //获取集合中第一个号码,因为第一个号码是最先加进来并且没取走的                     number = queueNumber.remove(0);              }              return number;       }      }

2、号码机器的类NumberMachine

定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。
将NumberMachine类设计成单例

/** * NumberMachine:号码机器(相当于我们去银行用的挂号机器) * 会返回三个号码管理器; * 号码机器在系统中只能有一个,要不然就会有几个相同的号码机器,窗口不知道去哪个号码机上拿号码 */publicclass NumberMachine{       //三种类型的客户(普通,快速,vip)       private NumberManager commonManager = new NumberManager();       private NumberManager expressManager = new NumberManager();       private NumberManager vipManager = new NumberManager();             //get方法       public NumberManager getCommonManager() {              returncommonManager;       }       public NumberManager getExpressManager() {              returnexpressManager;       }       public NumberManager getVipManager() {              returnvipManager;       }             //单例设计模式中构造方法私有       private NumberMachine(){}       //单例设计模式,返回一个对象       publicstatic NumberMachine getInstance()       {              returninstance;       }       privatestatic NumberMachine instance = new NumberMachine();;      }

3、客户类型(CustomerType枚举类

系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。
重写toString方法,返回类型的中文名称。这是在后面编码时重构出来的,刚开始不用考虑。

/** * 客户类型(枚举):CustomerType */ publicenum CustomerType{       COMMON,EXPRESS,VIP;             public String toString()       {              switch(this)              {              caseCOMMON:                     return"普通";              caseEXPRESS:                     return"快速";              caseVIP:                     return name();              }              returnnull;       }}

4、业务窗口类ServiceWindow类

定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。 
定义三个方法分别对三种客户进行服务,为了观察运行效果,应详细打印出其中的细节信息

import java.util.Random;import java.util.concurrent.Executors; /** * 服务窗口类:ServiceWindow * 有两个属性,一个是窗口类型,一个是窗口号 */publicclass ServiceWindow{       //代表窗口类型(3种)枚举。默认普通,因为普通最多       private CustomerType type= CustomerType.COMMON;         privateintwindowId = 1;   //窗口号             //为什么只要get方法,因为以后可以设置窗口类型及号码,不要一修了窗口以后就不能更改了       publicvoid setType(CustomerType type) {              this.type = type;       }       publicvoid setWindowId(int windowId) {              this.windowId = windowId;       }        publicvoid start()       {              Executors.newSingleThreadExecutor().execute(new Runnable(){                     publicvoid run()                     {                            while(true)                            {                                   /*if(type==CustomerType.COMMON)                                   NumberMachine.getInstance().getCommonManager();                                   else if()                                   else if()*/                    //此处用switch更高效                                   switch(type)  //表达式中可放的类型byte short int char enum                                   {                                   //向号码管理器要号码,也就是要服务                                          caseCOMMON:                                                 commonService();                                                 break;                                          caseEXPRESS:                                                 expressService();                                                 break;                                          caseVIP:                                                 vipService();                                                 break;                                   }                            }                     }                          });       }                      //为普通客户服务                     privatevoid commonService() {                            //此处不能改为普通。因为VIP和快速窗口没任务是会来为普通服务                            String windowName = "第"+windowId+"号"+type+"窗口";                            Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();                            System.out.println(windowName+"正在获取任务");                            if(number!=null){                                   System.out.println(windowName+"正在为第"+number+"个"+"普通客户服务");                                   long beginTime = System.currentTimeMillis();                                   int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;                                   //服务时间1000-10000毫秒                                   long serveTime = new Random().nextInt(maxRand)+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+"秒");                            }else{                                   System.out.println(windowName+"没有取到任务,先休息1秒钟嘛");                                   try {                                          Thread.sleep(1000);                                   } catch (InterruptedException e) {                                          e.printStackTrace();                                   }                            }                     }                      //为快速客户服务                     privatevoid expressService() {                            String windowName = "第"+windowId+"号"+type+"窗口";                            Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();                            System.out.println(windowName+"正在获取任务");                            if(number!=null){                                   System.out.println(windowName+"正在为第"+number+"个"+type+"客户服务");                                   long beginTime = System.currentTimeMillis();                                   //int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;                                   //long serveTime = new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;                                   try {                                          //快速客户只要最短的时间                                          Thread.sleep(Constants.MIN_SERVICE_TIME);                                   } catch (InterruptedException e) {                                          e.printStackTrace();                                   }                                   long costTime = System.currentTimeMillis()-beginTime;                                   System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");                            }else{                                   System.out.println(windowName+"没有取到任务!");                                   //快速窗口和VIP窗口没有获取到任务就去服务普通客户                                   commonService();                            }                     }                                         //为VIP客户服务                     privatevoid vipService() {                            String windowName = "第"+windowId+"号"+type+"窗口";                            Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();                            System.out.println(windowName+"正在获取任务");                            if(number!=null){                                   System.out.println(windowName+"正在为第"+number+"个"+type+"客户服务");                                   long beginTime = System.currentTimeMillis();                                   int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;                                   long serveTime = new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;                                   try {                                          Thread.sleep(serveTime);                                   } catch (InterruptedException e) {                                          e.printStackTrace();                                   }                                   long costTime = System.currentTimeMillis()-beginTime;                                   System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");                            }else{                                   System.out.println(windowName+"没有取到任务!");                                   commonService();                            }                     }}

5、主类(MainClass

用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。
接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。

<span style="font-size:18px;">import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit; publicclass MainClass{       publicstaticvoid main(String[] args)       {              //4个普通窗口              for(int i=1;i<5;i++)              {                     ServiceWindow commonWindow = new ServiceWindow();                     commonWindow.setWindowId(i);  //设置窗口号                     commonWindow.start();    //开始服务              }              //快速窗口              ServiceWindow expressWindow = new ServiceWindow();              expressWindow.setType(CustomerType.EXPRESS);  //设置窗口号              expressWindow.start();              //vip窗口              ServiceWindow vipWindow = new ServiceWindow();              vipWindow.setType(CustomerType.VIP);              //vipWindow.setWindowId(6);               vipWindow.start();                             //模拟客户来服务,往数组中添加号码              Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                            new Runnable(){                                   publicvoid run()                                   {                                          Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager();                                          System.out.println(number+"号普通客户等待服务!");                                   }},                            0,                            Constants.COMMON_CUSTOMER_INTERVAL_TIME,                            TimeUnit.SECONDS);                           Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                            new Runnable(){                                   publicvoid run()                                   {                                          Integer number = NumberMachine.getInstance().getVipManager().generateNewManager();                                          System.out.println(number+"号VIP客户等待服务!");                                   }},                            0,                            //vip:普通客户为1:6                            Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,                                 TimeUnit.SECONDS);                           Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                            new Runnable(){                                   publicvoid run()                                   {                                          Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager();                                          System.out.println(number+"号快速客户等待服务!");                                   }},                            0,                            Constants.COMMON_CUSTOMER_INTERVAL_TIME*2,                                 TimeUnit.SECONDS);       } }</span>

程序结果如下:




---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗太怕人了怎么办都不敢出门 媳妇和婆婆晚上都不想带孩子怎么办 婆婆和媳妇带孩子观念不一样怎么办 婆婆给媳妇买了不喜欢的家具怎么办 断奶后宝宝对奶粉很抗拒怎么办 两岁宝宝断奶不喝奶粉怎么办 宝宝两岁了断奶后奶粉不吃怎么办 宝宝断奶两天了不愿意吃奶粉怎么办 一岁四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶不喝奶粉怎么办 四个月宝宝断奶后不吃奶粉怎么办 2岁的宝宝不开口说话怎么办 一周岁宝宝断奶不喝奶粉怎么办 八个月宝宝断奶不喝奶粉怎么办 婆家人总是用心机对待娘家人怎么办 婆婆老是背后说我娘家人坏话怎么办 婆家姐带孩子住娘家不走怎么办? 老是想在娘家不想回婆家怎么办 娘家和婆家同时向我借钱怎么办 土地确权后娘家婆家都没有怎么办 结了婚婆家向娘家借钱怎么办? 婆婆的娘家人从我家住怎么办 八个月宝宝断奶后不吃奶粉怎么办 吃母乳的宝宝不吸奶嘴怎么办 宝宝吸了奶嘴不吸母乳怎么办 婴儿吃了奶嘴不吸母乳怎么办 十一个月宝宝断奶不喝奶粉怎么办 孩子三门成绩全不及格家长该怎么办 宝宝快十个月了还不会爬怎么办 小孩写字老把手向里扭曲怎么办 孩子该上四年级了数学差的很怎么办 孩子上三年级了数学成绩好差怎么办 三年级数学老考70-80分怎么办 叛逆期的孩子用死来威胁家长怎么办 叛逆期的孩子抽烟喝酒家长该怎么办 大学遇到不好的老师加课怎么办 两岁的宝宝脾气古怪不听话怎么办 16个月宝宝不听话脾气大怎么办 如果你很害怕去面对一件事怎么办 孩子上幼儿园哭老师不理孩子怎么办 发现幼儿园给孩子吃药片该怎么办