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

来源:互联网 发布:河钢唐钢 云计算 编辑:程序博客网 时间:2024/06/08 03:00
------- android培训、java培训、期待与您交流! ----------

一、需求分析:

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

 

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

 

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

 

       VIP客户:普通客户:快速客户 = 163

 

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

 

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

 

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

 

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

 

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

根据业务需求,案例的流程如下图:

二、用面向对象的思惟设计案例:

     根据业需求,案例应分为四个模块,

l 客户取号模块

l 客户服务号码管理模块

l 窗口服务模块

l 业务类型模块

l 客户生成和初始化模块

三、客户取号模块

        客户取号模块的主要职责为给客户分配业务服务号码,当有客户过来时,就会根据不同的客户,选择不同的业务。此模块依赖于号码管理模块,当调用此模块的取号方法时,就会调用号码管理模块生存业务号码,记录在号码管理模块中,并返回一个客户所需的号码。代码如下:

------------------------------------------------------------------------------------

package com.itcast.bank;

 

public class ClientNumberGenerate {

        private NumberManager numberManager=NumberManager.getNewInstance();

        public String getCommonNumber() {

                  return numberManager.setCommonNumber();

        }

 

        public String getExpressNumber() {

                  return numberManager.setExpressNumber();

        }

 

        public String getVIPNumber() {

                  return numberManager.setVIPNumber();

        }

}

------------------------------------------------------------------------------------

四、号码管理模块

        号码管理模块的职责是为二,首先,为客户取号模块服务,生成客户的业务列队号。返回给客户,并记录在对应的集合中,第二为:为窗口提供客户等待办理的业务号吗,窗口模块到号码管理模块去取号为客户服务。

        号码分为三类,第一类为以C打头的为普通客户的业务,第二类以E打头的为快速客户的务业,第三类为以V打头的为VIP客户的业务。代码如下:

------------------------------------------------------------------------------------

package com.itcast.bank;

 

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

import java.util.List;

import java.util.ListIterator;

 

public class NumberManager {

        private NumberManager() {

        }

 

        private static NumberManager newInstance = new NumberManager();

        private List<String> commonNumber = new ArrayList<String>();

        private List<String> expressNumber = new ArrayList<String>();

        private List<String> VIPNumber = new ArrayList<String>();

 

        public synchronized String getCommonNumber() {

                  String temp=null;

                  if(commonNumber.size()>0)

                           temp=commonNumber.remove(0);

                  return temp;

        }

 

        public synchronized String getExpressNumber() {

                  String temp=null;

                  if(expressNumber.size()>0)

                           temp=expressNumber.remove(0);

                  return temp;

        }

 

        public synchronized String getVIPNumber() {

                  String temp=null;

                  if(VIPNumber.size()>0)

                           temp=VIPNumber.remove(0);

                  return temp;

        }

 

        /**

         *用户客户取号时把号添加到列队去,并返回一个号码给客户;

         *

         * @return

         */

        public synchronized String setCommonNumber() {

                  String temp ="C"+commonNumber.size();

                  commonNumber.add(temp);

                  return temp;

        }

 

        /**

         *用户客户取号时把号添加到列队去,并返回一个号码给客户;

         *

         * @return

         */

        public synchronized String setExpressNumber() {

                  String temp ="E"+expressNumber.size();

                  expressNumber.add(temp);

                  return temp;

        }

 

        /**

         *用户客户取号时把号添加到列队去,并返回一个号码给客户;

         *

         * @return

         */

        public synchronized String setVIPNumber() {

                  String temp ="V"+VIPNumber.size();

                  VIPNumber.add(temp);

                  return temp;

        }

 

        public static NumberManager getNewInstance() {

                  return newInstance;

        }

 

}

------------------------------------------------------------------------------------

此类设计为单例模式,以便在系统中共享业务号码。

五、窗口服务模块

        窗口管理模块按业务分为三个对象,并从这三个对象中抽取出来一个抽象类,不管是哪种业务的窗口,它总会给客户办理业务,就是把办理业务的这个方法抽取出来。代码如下:

------------------------------------------------------------------------------------

package com.itcast.bank;

 

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

public abstract class AbstractWindowService {

        /**

         *服务客户并返回服务客户所需的时间()

         *

         * @return

         */

        private WindowType windowType = WindowType.COMMON;

        private Integer windowID = 1;

 

        public AbstractWindowService(WindowType windowType, Integer windowID) {

                  this.windowType = windowType;

                  this.windowID = windowID;

        }

 

        public void action() {

                  ScheduledExecutorService scheduledExecutorService = Executors

                                    .newScheduledThreadPool(1);

                  scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 

                           @Override

                           public void run() {

                                    String client = windowType.getServiceNumber();

                                    String window = null;

                                    int windowTypeID = windowType.ordinal();

                                    if (windowTypeID == 0)

                                              window = "普通窗口";

                                    else if (windowTypeID == 1)

                                              window = "快速窗口";

                                    if (windowTypeID == 2)

                                              window = "VIP窗口";

                                    if (client != null) {

                                              long start = System.currentTimeMillis();

                                              AbstractWindowService.this.service(windowType);

                                              long end = System.currentTimeMillis() - start;

                                              System.out.println(window + "" + windowID + "服务" + client

                                                                + "总共耗时为:" + end/1000+ "");

                                    } else {

                                              System.out.println(window + "" + windowID +"处于空闲中....");

                                    }

                           }

                  }, 1, 1, TimeUnit.SECONDS);

 

        }

 

        public abstract void service(WindowType windowType);

}

------------------------------------------------------------------------------------

在此对象中的action方法中定义一个定时器,用定期到号码管理器去取号,当取到号时,就为客户服务。此对象跟业务类型绑定在一起,带有不同的业务类型,就代码不同类型的业务类,通过业务类型,就可以依次得到各个业务类型对应的业务号码,此对象是一个enum类型的对象。如下:

------------------------------------------------------------------------------------

package com.itcast.bank;

 

public enum WindowType {

        COMMON, EXPRESS, VIP;

        private NumberManager numberManager = NumberManager.getNewInstance();

        public String getServiceNumber() {

                  String temp=null;

                  switch (WindowType.valueOf(this.name())) {

                  case COMMON:

                           return numberManager.getCommonNumber();

                  case EXPRESS:

                           temp=numberManager.getExpressNumber();

                           if(temp==null)

                                    temp=numberManager.getCommonNumber();

                           return temp;

                  case VIP:

                           temp=numberManager.getVIPNumber();

                           if(temp==null)

                                    temp=numberManager.getCommonNumber();

                           return temp;

                  }

                  return temp;

                  

        }

 

        @Override

        public String toString() {

                  switch (WindowType.valueOf(this.name())) {

                  case COMMON:

                           return "普通客户";

                  case EXPRESS:

                           return "快速客户";

                  case VIP:

                           return "VIP客户";

                  }

                  return null;

        }

}

------------------------------------------------------------------------------------

下为各个窗口所办里业务的对象:

普通窗口办理业务:

------------------------------------------------------------------------------------

 package com.itcast.bank;

 

public class CommonWindow extends AbstractWindowService {

 

        public CommonWindow(Integer windowID) {

                  super(WindowType.COMMON,windowID);

                  // TODO Auto-generated constructor stub

        }

 

        @Override

        public void service(WindowType windowType) {

                  try {

                           Thread.sleep(2000);

                  } catch (InterruptedException e) {

                           // TODO Auto-generated catch block

                           e.printStackTrace();

                  }

        }

 

}

快速窗口办理业务

------------------------------------------------------------------------------------

package com.itcast.bank;

 

public class ExpressWindow extends AbstractWindowService {

 

        public ExpressWindow(Integer windowID) {

                  super(WindowType.EXPRESS, windowID);

                  // TODO Auto-generated constructor stub

        }

 

        @Override

        public void service(WindowType windowType) {

                  try {

                           Thread.sleep(500);

                  } catch (InterruptedException e) {

                           // TODO Auto-generated catch block

                           e.printStackTrace();

                  }

        }

 

}

VIP窗口办理业务

------------------------------------------------------------------------------------

package com.itcast.bank;

 

public class VIPWindow extends AbstractWindowService {

 

        public VIPWindow(Integer windowID) {

                  super(WindowType.VIP, windowID);

                  // TODO Auto-generated constructor stub

        }

 

        @Override

        public void service(WindowType windowType) {

                  try {

                           Thread.sleep(1000);

                  } catch (InterruptedException e) {

                           // TODO Auto-generated catch block

                           e.printStackTrace();

                  }

        }

 

}

五、客户生成和初始化模块

------------------------------------------------------------------------------------

此模块用户初始化各个业务窗口,并按比例需求生成不同办理业务的客户,代码如下:

package com.itcast.bank;

 

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

 

public class ServiceHall {

        public static void main(String[] args) {

                  for (int i = 1; i < 5; i++)

                           new CommonWindow(i).action();

                  new ExpressWindow(1).action();

                  new VIPWindow(1).action();

                  //普通客户

                  Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

 

                           @Override

                           public void run() {

                                    String serviceNumber=new ClientNumberGenerate().getCommonNumber();

                                    System.out.println("有一个普通客户"+serviceNumber+"在等待办理");

                           }

                  }, 1, 1, TimeUnit.SECONDS);

                  //快速客户

                  Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

 

                           @Override

                           public void run() {

                                    String serviceNumber=new ClientNumberGenerate().getExpressNumber();

                                    System.out.println("有一个快速客户"+serviceNumber+"在等待办理");

                           }

                  }, 3, 3, TimeUnit.SECONDS);

                  //VIP客户

                  Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {

 

                           @Override

                           public void run() {

                                    String serviceNumber=new ClientNumberGenerate().getVIPNumber();

                                    System.out.println("有一个VIP客户"+serviceNumber+"在等待办理");

                           }

                  }, 6, 6, TimeUnit.SECONDS);

 

        }

}

五、经验总结

------------------------------------------------------------------------------------

        此案例的成功之处在于模块职责分工得很明确,各模块分别实现属于自己功能,然后再将各个模块组合成一个系统。最大的成功就是用面向对象的思惟来为模块分配职责,如果职责分配不清的话,那么各个模块之间的偶合度大,会给编码带来麻烦。

        当在做一个项目时,不能一拿到需求就要去写代码,而是应该把需求做详细的分析之后,把项目的各个模块职责划分清楚,在思想上清析了,写起代码来时,才会得心应手,在对项目似懂非懂的情况下是不能去写代码的。

        当我们在分析一个项目时,一定要以面向对象的思惟去考虑问,却不能想这模块怎么做,那模块怎么做,而是从全局性出发,考虑的应该是这模块分为几个对象,分别提供是什么样的功能,为哪些模块提供服务等。