黑马程序员--银行业务调度系统分析讲解及实现
2013-09-27 16:55
453 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
银行业务调度系统
需求:
模拟实现银行业务调度系统逻辑,具体需求如下:
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方式展现程序运行结果。
需求分析:
面向对象的分析和设计
1、有三种对应类型的客户:VIP客户,普通客户,快速客户。异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。
分析:
(1)三种类型的客户需要一个取号机产生,该取号机只有一个,因此应该设计为单例模式。
(2)而这三类号码的生成机制相同,因此可以封装为一个内部类。即号码管理类,负责管理号码,包括生成号码、取号码。
(3)取号机取出的号码根据客户类型可以分为三类,VIP客户,普通客户,快速客户。即生成三类号码管理器。
因此,应该设计以下两个类:
号码管理器:用于管理所有号码,包括生成号码、取号。可以是取号机的内部类。
取号机:用于生成不同类型的号码管理器。单例模式。
2、 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
分析:
(1)本质上所有窗口都是一样的,只不过按上了不同的标识。不同的窗口就是不同的实例对象。
(2)服务窗口要拥有设置窗口类型的行为,设置窗口号的行为,以及获取窗口类型的行为,开启服务的行为。
(3)开启服务的同时,应该能够根据不同的实例对象类型来进行不同的服务。
(4)其中的三种类型可以设计为enum。
因此:应该设计一个类:
服务窗口:用于生成不同类型的实例对象,并根据不同的类型来进行不同的服务。
1、窗口类型、窗口号
2、初始化时就应该初始化窗口类型。
3、设置窗口号、设置窗口类型
4、服务窗口有三种服务方法,分别对应三种类型的酷客户
3、需要一个主类来启动整个调度系统
(1)该类中声明4个普通窗口,分别设置类型,设置窗口号,并开启服务。
(2)分别产生1个快速窗口和1个VIP窗口,设置类型,并开启服务。
(3)生成三个模拟客户取号的过程,按比例在一定期限内,随机产生不同类型的客户。
系统实现代码:
一、取号器 NumMachine
二、服务窗口 ServiceWindow
三、客户类型 CustomType(enum类型)
四、静态值Constants
五、主方法类 MainClass
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
银行业务调度系统
需求:
模拟实现银行业务调度系统逻辑,具体需求如下:
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方式展现程序运行结果。
需求分析:
面向对象的分析和设计
1、有三种对应类型的客户:VIP客户,普通客户,快速客户。异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。
分析:
(1)三种类型的客户需要一个取号机产生,该取号机只有一个,因此应该设计为单例模式。
(2)而这三类号码的生成机制相同,因此可以封装为一个内部类。即号码管理类,负责管理号码,包括生成号码、取号码。
(3)取号机取出的号码根据客户类型可以分为三类,VIP客户,普通客户,快速客户。即生成三类号码管理器。
因此,应该设计以下两个类:
号码管理器:用于管理所有号码,包括生成号码、取号。可以是取号机的内部类。
取号机:用于生成不同类型的号码管理器。单例模式。
2、 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
分析:
(1)本质上所有窗口都是一样的,只不过按上了不同的标识。不同的窗口就是不同的实例对象。
(2)服务窗口要拥有设置窗口类型的行为,设置窗口号的行为,以及获取窗口类型的行为,开启服务的行为。
(3)开启服务的同时,应该能够根据不同的实例对象类型来进行不同的服务。
(4)其中的三种类型可以设计为enum。
因此:应该设计一个类:
服务窗口:用于生成不同类型的实例对象,并根据不同的类型来进行不同的服务。
1、窗口类型、窗口号
2、初始化时就应该初始化窗口类型。
3、设置窗口号、设置窗口类型
4、服务窗口有三种服务方法,分别对应三种类型的酷客户
3、需要一个主类来启动整个调度系统
(1)该类中声明4个普通窗口,分别设置类型,设置窗口号,并开启服务。
(2)分别产生1个快速窗口和1个VIP窗口,设置类型,并开启服务。
(3)生成三个模拟客户取号的过程,按比例在一定期限内,随机产生不同类型的客户。
系统实现代码:
一、取号器 NumMachine
package com.heima.exam.bank; import java.util.*; /** * 取号器 * 用于生成不同类型的号码管理器 * * 1、一般一个银行中只有一个取号器,因此设计为单利模式 * 2、取号器中有一个号码生成器,因此设计一个内部类:号码生成器。 * 3、号码生成器在实例化时即指明是哪一种类型的生成器 * 4、号码生成器管理号码,包括生成好码、取号。 * * @author zhangyunfei * */ public class NumMachine { //将取号机设置为单例模式 private static NumMachine numMachine = new NumMachine(); private NumMachine(){} public static NumMachine getInstance(){ return numMachine; } //分别声明三种类型的号码生成器 private NumManager commonNumMagager = new NumManager(CustomerType.COMMON); private NumManager expressNumMagager = new NumManager(CustomerType.EXPRESS); private NumManager vipNumMagager = new NumManager(CustomerType.VIP); //分别生成三中类型号码生成器的获取方法 public NumManager getCommonNumMagager() { return commonNumMagager; } public NumManager getExpressNumMagager() { return expressNumMagager; } public NumManager getVipNumMagager() { return vipNumMagager; } /** * 号码管理器。 * 用于管理所有号码,包括生成号码、取号。是取号机的内部类。 * @author zhangyunfei * */ class NumManager{ private List<Integer> numList = new LinkedList<Integer>(); //一个存储号码的集合 private Integer num = 0; //模拟顾客的数量 private CustomerType numType = null; //该号码产生器的类型 //初始化时即定义该号码产生器实例的类型 public NumManager(CustomerType type){ this.numType = type; } //来一个新的顾客,在等待服务。共享同一个集合,同步 public synchronized Integer createNum(){ numList.add(++num); System.out.println(numType + "客户_" + num + "正在等待服务..."); return num; } //取号。如果该实例类型的客户存在,则返回最前边的客户号,否则返回null。共享同一个集合,同步 public synchronized Integer fetchNum(){ if(!numList.isEmpty()){ return numList.remove(0); } return null; } } }
二、服务窗口 ServiceWindow
package com.heima.exam.bank; import java.util.Random; import java.util.concurrent.Executors; /** * 服务窗口类 * 用于生成不同类型的实例对象,并根据不同的类型来进行不同的服务。 * 成员变量:窗口类型、窗口号、该窗口是否开启服务 * 成员方法:开启服务、不同的服务方法、关闭服务等 * * @author zhangyunfei * */ public class ServiceWindow { //服务窗口的类型,默认为普通类型 private CustomerType windowType = null; //服务窗口号,默认为1号 private int windowNum = 1; //该窗口是否开启服务 private boolean isService = false; //初始化窗口时就应该初始化窗口类型 public ServiceWindow(CustomerType windowType){ this.windowType = windowType; } //开启服务,根据不同的窗口类型,进行不同的服务 public void start(){ this.isService = true; //开启服务 Executors.newSingleThreadExecutor().execute( new Runnable(){ @Override public void run(){ switch(windowType){ case COMMON: while(isService){ commonService(); //开启普通客户服务窗口 } break; case EXPRESS: while(isService){ expressService(); //开启快速客户服务窗口 } break; case VIP: while(isService){ vipService(); //开启VIP客户服务窗口 } break; } } }); } //下班了 public void closeService(){ this.isService = false; System.out.println(this.windowNum+this.windowNum + "下班了!"); } /* * 定义三种服务方法 */ //普通服务方法。1、首先叫号 2、判断是否有号。有号则服务,无号则等待1秒钟 3、依次循环 public void commonService(){ //1、叫号 System.out.println(this.windowType+"_"+this.windowNum + "正在叫普通号..."); Integer num = NumMachine.getInstance().getCommonNumMagager().fetchNum(); //2、判断是否有号 if(num != null){//有号 //开始服务 System.out.println(this.windowType+"_"+this.windowNum + " 窗口正在为 " +"普通号_"+num + "服务>>>>>"); int subTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int comServiceTime = new Random().nextInt(subTime) + 1 + Constants.MIN_SERVICE_TIME; try { Thread.sleep(comServiceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.windowType+"_"+this.windowNum + " 窗口为 " + this.windowType+"_"+num + "服务over,总耗时为"+comServiceTime/1000 + "s。欢迎下次光临!"); }else{//无号 System.out.println(this.windowType+"_"+this.windowNum + " 窗口没有取到普通号,等待1s"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //快速服务方法。1、首先叫号 2、判断是否有号。有号则服务;无号则叫普通号,为普通号服务 3、依次循环 public void expressService(){ System.out.println(this.windowType+"_"+this.windowNum + "正在叫快速号..."); //1、叫号 Integer num = NumMachine.getInstance().getExpressNumMagager().fetchNum(); //2、判断是否有号 if(num != null){//有号 //开始服务 System.out.println(this.windowType+"_"+this.windowNum + " 窗口正在为 " + "快速号_"+num + "服务>>>>>"); int comServiceTime = Constants.MIN_SERVICE_TIME; //快速号的服务时间为最小值 try { Thread.sleep(comServiceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.windowType+"_"+this.windowNum + " 窗口为 " + "快速号_"+num + "服务over,总耗时为"+comServiceTime/1000 + "s。欢迎下次光临!"); }else{//无号 System.out.println(this.windowType+"_"+this.windowNum + " 窗口没有取到快速号,开始叫普通号"); commonService(); //快速窗口优先为快速客户服务,没有则为普通客户服务 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //VIP服务方法。1、首先叫号 2、判断是否有号。有号则服务;无号则叫普通号,为普通号服务 3、依次循环 public void vipService(){ System.out.println(this.windowType+"_"+this.windowNum + "正在叫VIP号..."); //1、叫号 Integer num = NumMachine.getInstance().getCommonNumMagager().fetchNum(); //2、判断是否有号 if(num != null){//有号 //开始服务 System.out.println(this.windowType+"_"+this.windowNum + " 窗口正在为 " + "VIP_"+num + "服务>>>>>"); int subTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int comServiceTime = new Random().nextInt(subTime) + 1 + Constants.MIN_SERVICE_TIME; try { Thread.sleep(comServiceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.windowType+"_"+this.windowNum + " 窗口为 " +"VIP_"+num + "服务over,总耗时为"+comServiceTime/1000 + "s。欢迎下次光临!"); }else{//无号 System.out.println(this.windowType+"_"+this.windowNum + " 窗口没有取到VIP号,则叫普通号"); commonService(); //VIP窗口优先为VIP客户服务,没有则为普通客户服务 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public CustomerType getWindowType() { return windowType; } public void setWindowType(CustomerType windowType) { this.windowType = windowType; } public int getWindowNum() { return windowNum; } public void setWindowNum(int windowNum) { this.windowNum = windowNum; } }
三、客户类型 CustomType(enum类型)
package com.heima.exam.bank; /** * 客户类型 * * @author zhangyunfei * */ public enum CustomerType { COMMON,EXPRESS,VIP; //覆盖toString()方法,直接打印时以友好的字符串形式出现 @Override public String toString(){ switch(this){ case COMMON: return "普通"; case EXPRESS: return "快速"; case VIP: return name(); } return null; } }
四、静态值Constants
package com.heima.exam.bank; public class Constants { public static int MAX_SERVICE_TIME = 10000;//最大的服务时间为10s public static int MIN_SERVICE_TIME = 1000;//最小的服务时间为1s }
五、主方法类 MainClass
package com.heima.exam.bank; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 主方法类 * 1、产生服务窗口 * 2、模拟客户取号 * * @author zhangyunfei * */ public class MainClass { public static void main(String[] args) { /** * 产生服务窗口,并开启 */ //产生4个普通窗口 for(int i = 1; i < 5; i++){ ServiceWindow comWindow = new ServiceWindow(CustomerType.COMMON); //产生普通窗口 comWindow.setWindowNum(i); //设置窗口号 comWindow.start(); } //产生1个快速窗口 ServiceWindow expressWindow = new ServiceWindow(CustomerType.EXPRESS); //产生快速窗口 expressWindow.start(); //产生1个VIP窗口 ServiceWindow vipWindow = new ServiceWindow(CustomerType.VIP); //产生VIP窗口 vipWindow.start(); /** * 模拟客户到取号机取号 */ //普通客户取号 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ @Override public void run(){ NumMachine.getInstance().getCommonNumMagager().createNum();//普通客户取号 } }, 0, 1, TimeUnit.SECONDS); //快速客户取号 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ @Override public void run(){ NumMachine.getInstance().getExpressNumMagager().createNum();//快速客户取号 } }, 0, 2, TimeUnit.SECONDS); //VIP客户取号 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ @Override public void run(){ NumMachine.getInstance().getVipNumMagager().createNum();//VIP客户取号 } }, 0, 6, TimeUnit.SECONDS); } }
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员--银行业务调度系统分析设计和Java代码的实现
- 黑马程序员:银行业务调度系统分析及代码实现
- 黑马程序员-JAVA学习之银行业务调度系统分析与实现
- 黑马程序员_银行业务调度系统分析
- 黑马程序员_java银行业务调度系统的分析、设计、实现
- 黑马程序员-银行业务调度系统
- 黑马程序员---银行业务调度系统
- 黑马程序员 7k面试题破解: 银行业务调度系统
- Java加密算法的实现实例细节分析讲解
- 黑马程序员-张孝祥银行业务调度系统
- 黑马程序员 Java面向对象——银行业务调度系统
- 黑马程序员——银行业务调度系统
- 黑马程序员--7k之银行业务调度系统
- 黑马程序员_银行业务调度系统需求分析
- 黑马程序员---7k面试题(银行业务调度系统)
- 黑马程序员---银行业务调度系统
- Android XListView实现原理讲解及分析
- qq农场,不开通牧场也能给好友添加牧草(数据抓包分析,实现源码,图片讲解)
- Android LaunchMode 和ams的关系的分析和实现和讲解总结
- 【黑马程序员】银行业务调度系统