---------- android培训java培训、期待与您交流! ----------

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

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

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

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

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

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

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

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

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

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

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

  1、有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务

  (1)首先,每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,我想到要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。

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

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

  各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。

三、由需求分析而抽象出来的类及其方法的关系图

  

四、代码实现

  (一)NumberManager类

 package com.itheima.bank;
/* NumberManager类:
* 1.定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。
* 2.定义一个产生新号码的方法和获取马上要为之服务的号码的方法。
* 3.这两个方法被不同的线程操作了相同的数据, 所以要进行同步。
* */
import java.util.ArrayList;
import java.util.List;
public class NumberManager {
private int lastNumber = 0;
private List<Integer> queueNumber = new ArrayList<Integer>();
public synchronized Integer generateNewNumber(){
queueNumber.add(++lastNumber);
return lastNumber;
}
public synchronized Integer fetchNumber(){
if(queueNumber.size()>0){
return queueNumber.remove(0);
}else{
return null;
}
}
}

  (二)NumberMachine

 package com.itheima.bank;

 /* NumberMachine类
* 1.定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器。
* 2.定义三个对应的方法来返回这三个NumberManager对象。
* 3.将NumberMachine类设计成单例。
*/
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 NumberMachine(){}
private static NumberMachine instance = new NumberMachine();
public static NumberMachine getInstance(){
return instance;
}
}

  (三)CustomerType枚举类

 package com.itheima.bank;
/*
* CustomerType枚举类
* 1.系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。
* 2.重写toString方法,返回类型的中文名称。这是在后面编码时重构出来的,刚开始不用考虑。
*/
public enum CustomerType {
COMMON,EXPRESS,VIP;
//返回中文名称
@Override
public String toString(){
switch(this){
case COMMON:
return "普通";
case EXPRESS:
return "快速";
case VIP:
return name();//name()返回此枚举常量的名称。
}
return null;
}
}

  (四)ServiceWindow

 package com.itheima.bank;

 import java.util.Random;
import java.util.concurrent.Executors;
/*
* ServiceWindow类
* 1.定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。
* 2.定义三个方法分别对三种客户进行服务,为了观察运行效果,应详细打印出其中的细节信息。
*/
public class ServiceWindow {
private CustomerType type = CustomerType.COMMON;
private int number = 1; public void setNumber(int number) {
this.number = number;
} public void setType(CustomerType type) {
this.type = type;
} 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() {
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
String windowName = "第" + number + "号" + type + "窗口";
System.out.println(windowName + "开始获取普通任务!");
if (serviceNumber != null) {
System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
int serviceTime = new Random().nextInt(maxRandom) + 1 + Constants.MIN_SERVICE_TIME; try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime / 1000 + "秒"); } else {
System.out.println(windowName + "没有取到普通任务,正在空闲一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} private void expressService() {
Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();
String windowName = "第" + number + "号" + type + "窗口";
System.out.println(windowName + "开始获取快速任务!");
if (serviceNumber != null) {
System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务");
int serviceTime = Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "完成为第" + serviceNumber + "号快速客户服务,总共耗时" + serviceTime / 1000 + "秒");
} else {
System.out.println(windowName + "没有取到快速任务");
commonService();
}
} private void vipService() {
Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();
String windowName = "第" + number + "号" + type + "窗口";
System.out.println(windowName + "正在获取vip任务");
if (serviceNumber != null) {
System.out.println(windowName + "开始为第" + serviceNumber + "号vip客户服务");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
int serviceTime = new Random().nextInt(maxRandom)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "完成为第" + serviceNumber + "号vip客户服务,总共耗时" + serviceTime / 1000 + "秒");
} else {
System.out.println(windowName + "没有取到vip任务!");
commonService();
}
}
}

  (五)Constants

 package com.itheima.bank;

 /*Constants类,定义三个常量:
* 1.MAX_SERVICE_TIME:客户办理业务所需时间有最大值
* 2.MIN_SERVICE_TIME:客户办理业务所需时间有最小值
* 3.COMMON_CUSTOMER_INTERVAL_TIME:普通客户出现的时间间隔
* */
public class Constants {
public static int MAX_SERVICE_TIME = 10000;
public static int MIN_SERVICE_TIME = 1000;
/* 每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来
* 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户,所以,
* 1秒钟产生一个普通客户比较合理,*/
public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}

  (六)MainClass

 package com.itheima.bank;

 import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainClass {
/* MainClass类
*1.用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。
* 2.接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。
*/
public static void main(String[] args) { //产生4个普通窗口
for(int i=1;i<5;i++){
ServiceWindow window = new ServiceWindow();
window.setNumber(i);
window.start();
} //产生1个快速窗口
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start(); //产生1个VIP窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start(); //普通客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME, //每隔1秒钟,有一个普通客户
TimeUnit.SECONDS
); //快速客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*2,
TimeUnit.SECONDS
);
//VIP客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS
);
}
}

---------- android培训java培训、期待与您交流! ----------

黑马程序员——【Java高新技术】——案例:银行业务调度系统的更多相关文章

  1. 【黑马18期Java毕业生】黑马程序员Java全套资料+视频+工具

        Java学习路线图引言:        黑马程序员:深知广大爱好Java的人学习是多么困难,没视频没资源,上网花钱还老被骗. 为此我们历时一个月整理这套Java学习路线图,不管你是不懂电脑的小 ...

  2. 黑马程序员_高新技术之javaBean,注解,类加载器

    ----------- android培训.java培训.java学习型技术博客.期待与您交流! ---------- 第一部分 javaBean 一,由内省引出javaBean 1,内省: 内省对应 ...

  3. 黑马程序员Java基础班+就业班课程笔记全发布(持续更新)

    正在黑马学习,整理了一些课程知识点和比较重要的内容分享给大家,也是给自己拓宽一些视野,仅供大家交流学习,大家有什么更好的内容可以发给我 ,现有黑马教程2000G  QQ 1481135711 这是我总 ...

  4. 黑马程序员----java基础笔记中(毕向东)

    <p>------<a href="http://www.itheima.com" target="blank">Java培训.Andr ...

  5. 黑马程序员——JAVA基础之泛型和通配符

    ------- android培训.java培训.期待与您交流! ---------- 泛型:            JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...

  6. 黑马程序员——JAVA基础之简述面向对象,类,变量,匿名对象

    ------- android培训.java培训.期待与您交流! ---------- 面向对象: 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程 强调的是功能行为 面向对象 将 ...

  7. 黑马程序员——JAVA基础之语法、命名规则

    ------- android培训.java培训.期待与您交流! ---------- 1.java语言组成:关键字,标识符,注释,常量和变量,运算符,语句,函数,数组. 2.java关键字:被Jav ...

  8. 黑马程序员——Java高级应用(一)

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

  9. 黑马程序员——JAVA基础之File类,递归,打印流,合并切割流

    ------- android培训.java培训.期待与您交流! ---------- File类 用来将文件或者文件夹封装成对象 方便对文件与文件夹的属性信息进行操作. File对象可以作为参数传递 ...

  10. 黑马程序员——JAVA基础之多线程的安全问题

    ------- android培训.java培训.期待与您交流! ---------- 导致多线程出现问题的一个特殊的状态:就绪.具备了执行资格,但是还没有获取资源. 导致安全问题的出现的原因: 1. ...

随机推荐

  1. Response.Write("<script>alert('弹出对话框!')</script>") 后跟Response.Redirect("page.aspx");不能弹出对话框,直接跳转页面了 如何解?

    Response.Write和Response.Redirect一起用的时候就会这样,write脚本和redirect脚本不能同时使用,这样不会执行脚本,最好使用ClientScript 改进方法: ...

  2. 虚拟化--IO虚拟化基本原理

    本文话题: IO虚拟化概述 设备发现 访问截获 设备模拟 设备共享基于软件的IO虚拟化 基于前端后端的IO虚拟化基于硬件的IO虚拟化 概述 从处理器的角度看,外设是通过一组I/O资源(端口I/O或者是 ...

  3. iOS:iOS中的多控制器管理

    iOS中的控制器有三种创建方式: 1.通过storyboard创建 UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@" ...

  4. bat中rar压缩命令

    数据库备份,导出的dmp 文件比较大,需要压缩,压缩后大小能变为原来十分之一左右吧. 写的是批处理的语句,每天调用,自动导出dmp 文件,压缩删除原文件. 首先写下路径,先将压缩软件的路径写入系统的环 ...

  5. 全端开发必备!10个最好的 Node.js MVC 框架

      Node.js 是最流行的 JavaScript 服务端平台,它允许建立可扩展的 Web 应用程序.Node.js 包含不同类型的框架,如 MVC 框架.全栈框架.REST API  以及大量的服 ...

  6. Intellij Idea 编辑器使用之 安装、破解 版本15.0.1

    工欲善其事必先利其器. 早就听说了Intellij idea 这个编辑器.也曾尝试过,由于对eclipse,myeclipse用的比较习惯.顺手了,所以对于Intellij idea 也只是浅尝辄止. ...

  7. Microsoft Help Viewer

    Microsoft Help Viewer 1.0 Microsoft Help Viewer 2.0 Help Library 管理器 -Microsoft Help 查看器 打开VS 2010   ...

  8. Spring Framework的核心:IOC容器的实现

    2.1   Spring IoC容器概述 2.1.1 IoC容器和依赖反转模式 依赖反转的要义,如果合作对象的引用或依赖关系的管理由具体对象来完成,会导致代码的高度耦合和可测性的降低.依赖控制反转的实 ...

  9. 小游戏Item表

    [Config]1|0|我|1|10|500|0|8|2|4|b5222d10-55a7-4789-8541-8e7430345d54|0|0[Config] [Config]2|1|公主|1|0|5 ...

  10. Hollister Outlet Store

    (link to hollisterco site), It's a major try. After a photographer's viewpoint, Which roughly splend ...