---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------

需求

模拟实现银行业务调度系统逻辑,具体需求如下:

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

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

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

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

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

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

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

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

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

分析

用 面向对象的思想分析和设计

1. 有三种对应类型的客户:VIP客户,普通客户,快速客户。

异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。

1) 首先,经常在银行办理业务的人更有利于理解本系统,例如,我跑过一次银行,对银行的这个业务算是比较熟悉了,我知道每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,我想到要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。

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

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

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

2) 如果我不是多次亲身经历银行的这种业务,再加之积累了大量面向对象的应用开发经验,我也不知道能否轻松进行这种设计,能否发掘出其中隐含的对象信息,我真说不出具体的经验是什么,就是日积月累出来的一种感觉。

3. 类图

编码

NumberManager类

1. 定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。

2. 定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步。

源码:

package com.isoftstone.intervierw.bank;

import java.util.ArrayList;

import java.util.List;

public class NumberManager {

private int lastNumber;

privateList<Integer> queueNumbers = new ArrayList<Integer>();

public synchronized Integer generateNewNumber() {

queueNumbers.add(++lastNumber);

return lastNumber;

}

public synchronized Integer fetchNumber() {

if(queueNumbers.size()>0) {

return queueNumbers.remove(0);

}

return null;

}

}

NumberMachine类

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

2. 将NumberMachine类设计成单例。

源码:

package com.isoftstone.intervierw.bank;

public class NumberMachine {

private NumberMachine() {}

private static NumberMachine instance =null;

public static NumberMachine getInstance() {

if(instance==null) {

synchronized (NumberMachine.class) {

if(instance==null) {

instance= new NumberMachine();

return instance;

}

}

}

return instance;

}

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;

}

}

CustomerType枚举类

1. 系统中有三种类型的客户,所以用定义一个枚举类,其中定义三个成员分别表示三种类型的客户。

2. 重写toString方法,返回类型的中文名称。这是在后面编码时重构出来的。

源码:

package com.isoftstone.intervierw.bank;

public enum CustomerType {

COMMON,EXPRESS,VIP;

public String toString() {

switch(this) {

case COMMON:

return "普通";

case EXPRESS:

return "快速";

default:

return name();

}

}

}

ServiceWindow类

1. 定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同的方法。

2. 定义三个方法分别对三种客户进行服务,为了观察运行效果,应详细打印出其中的细节信息。

源码:

package com.isoftstone.intervierw.bank;

import java.util.Random;

import java.util.concurrent.Executors;

public class ServiceWindow {

private CustomerType type;

private int windowId;

public void setType(CustomerType type) {

this.type = type;

}

public void setWindowId(int windowId) {

this.windowId = windowId;

}

public void start() {

Executors.newSingleThreadExecutor().execute(new Runnable() {

@Override

public void run() {

while(true) {

switch(type) {

case COMMON:

commonService();

break;

case EXPRESS:

expressService();

break;

default:

vipService();

break;

}

}

}

});

}

private void commonService() {

Integer serviceNumber = NumberMachine.getInstance()

.getCommonManager().fetchNumber();

String windowName ="第"+windowId+"号"+type+"窗口";

System.out.println(windowName+"正在获取普通任务");

if(serviceNumber!=null) {

System.out.println(windowName+"获取到普通任务");

long startServiceTime =System.currentTimeMillis();

System.out.println("请"+serviceNumber+"号"+type+

"客户到"+windowId+"号"+type+"窗口");

System.out.println(windowName+"正在为"+serviceNumber+

"号普通客户服务");

try {

Thread.sleep(new Random().nextInt(Constant.MAX_SERVICE_TIME-

Constant.MIN_SERVICE_TIME)+Constant.MIN_SERVICE_TIME);

} catch (InterruptedException e) {

e.printStackTrace();

}

long serviceTime =System.currentTimeMillis()-startServiceTime;

System.out.println(windowName+"为第"+serviceNumber+"个普通客户服务,耗时"

+serviceTime/1000+"秒");

} else {

System.out.println(windowName+"没有获取到普通任务,休息1秒钟");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

private void expressService() {

Integer serviceNumber = NumberMachine.getInstance()

.getExpressManager().fetchNumber();

String windowName ="第"+windowId+"号"+type+"窗口";

System.out.println(windowName+"正在获取"+type+"任务");

if(serviceNumber!=null) {

System.out.println(windowName+"获取到"+type+"任务");

long startServiceTime =System.currentTimeMillis();

System.out.println("请"+serviceNumber+"号"+type+"客户到"+windowId+"号"+type+"窗口");

System.out.println(windowName+"正在为"+serviceNumber+"号"+type+"客户服务");

try {

Thread.sleep(new Random().nextInt(Constant.MAX_SERVICE_TIME-

Constant.MIN_SERVICE_TIME)+Constant.MIN_SERVICE_TIME);

} catch (InterruptedException e) {

e.printStackTrace();

}

long serviceTime =System.currentTimeMillis()-startServiceTime;

System.out.println(windowName+"为第"+serviceNumber+"个"+type+"客户服务,耗时"

+serviceTime/1000+"秒");

} else {

System.out.println(windowName+"没有获取到"+type+"任务,为普通窗口提供服务");

commonService();

}

}

private void vipService() {

Integer serviceNumber = NumberMachine.getInstance()

.getVipManager().fetchNumber();

String windowName ="第"+windowId+"号"+type+"窗口";

System.out.println(windowName+"正在获取"+type+"任务");

if(serviceNumber!=null) {

System.out.println(windowName+"获取到"+type+"任务");

long startServiceTime =System.currentTimeMillis();

System.out.println("请"+serviceNumber+"号"+type+"客户到"+windowId+"号"+type+"窗口");

System.out.println(windowName+"正在为"+serviceNumber+"号"+type+"客户服务");

try {

Thread.sleep(new Random().nextInt(Constant.MAX_SERVICE_TIME-

Constant.MIN_SERVICE_TIME)+Constant.MIN_SERVICE_TIME);

} catch (InterruptedException e) {

e.printStackTrace();

}

long serviceTime = System.currentTimeMillis()-startServiceTime;

System.out.println(windowName+"为第"+serviceNumber+"个"+type+"客户服务,耗时"

+serviceTime/1000+"秒");

} else {

System.out.println(windowName+"没有获取到"+type+"任务,为普通窗口提供服务");

commonService();

}

}

}

Constants类

1. 定义三个常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME。

源码:

package com.isoftstone.intervierw.bank;

public class Constant {

public static int MAX_SERVICE_TIME = 10000;

public static int MIN_SERVICE_TIME = MAX_SERVICE_TIME / 10;

public static int MIN_TIME = 1;

}

MainClass类

1. 用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。

2. 接着再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。

源码:

package com.isoftstone.intervierw.bank;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

public class MainClass {

public static void main(String[] args) {

final ServiceWindow vipServiceWindow = new ServiceWindow();

vipServiceWindow.setWindowId(6);

vipServiceWindow.setType(CustomerType.VIP);

vipServiceWindow.start();

final ServiceWindow expressServiceWindow = new ServiceWindow();

expressServiceWindow.setWindowId(5);

expressServiceWindow.setType(CustomerType.EXPRESS);

expressServiceWindow.start();

for(int i=1; i<=4; i++) {

final ServiceWindow commonServiceWindow = new ServiceWindow();

commonServiceWindow.setWindowId(i);

commonServiceWindow.setType(CustomerType.COMMON);

commonServiceWindow.start();

}

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable() {

@Override

public void run() {

Integer customerNumber= NumberMachine.getInstance()

.getCommonManager().generateNewNumber();

System.out.println(customerNumber+"号"+CustomerType.COMMON

+"客户正在等待服务");

}

},

0,

Constant.MIN_TIME,

TimeUnit.SECONDS);

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable() {

@Override

public void run() {

Integer customerNumber = NumberMachine.getInstance()

.getExpressManager().generateNewNumber();

System.out.println(customerNumber+"号"+CustomerType.EXPRESS

+"客户正在等待服务");

}

},

0,

Constant.MIN_TIME * 2,

TimeUnit.SECONDS);

Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

new Runnable() {

@Override

public void run() {

Integer customerNumber = NumberMachine.getInstance()

.getVipManager().generateNewNumber();

System.out.println(customerNumber+"号"+CustomerType.VIP

+"客户正在等待服务");

}

},

0,

Constant.MIN_TIME * 6,

TimeUnit.SECONDS);

}

}

---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------

黑马程序员_银行调度系统相关推荐

  1. 黑马程序员_银行调度系统学习总结

    ----------- android培训.java培训.java学习型技术博客.期待与您交流! ------------ 银行业务调度系统: 模拟实现银行业务调度系统逻辑,具体需求如下: ·银行内有 ...

  2. 黑马程序员__银行业务调度系统

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

  3. 黑马程序员_java_银行售票系统

    ------- android培训.java培训.期待与您交流! ---------- 银行业务调度系统 6个窗口 1-4  普通窗口 5 快速窗口(交费用的) 6 vip窗口 客户随机生成 1:6: ...

  4. 黑马程序员_异常(老毕视频总结及《疯狂java》补充)

    ----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+A ...

  5. 黑马程序员_毕向东_Java基础视频教程_Java基础学习知识点总结

    黑马程序员_毕向东_Java基础视频教程 Java基础学习知识点总结 2016年01月06日  day01 一.基础知识:软件开发 1.什么是软件?软件:一系列按照特定顺序组织的计算机数据和指令的集合 ...

  6. 黑马程序员_石头迷阵小游戏

    黑马程序员_石头迷阵小游戏 源代码 一些说明: 1)这些是我看b站黑马程序员的视频,自己手打的,想分享一下,如果有侵权啥的请联系我,马上删除 2)一些比较重要的我都有给注释 3)工具idea idk版 ...

  7. 解析python网络爬虫pdf 黑马程序员_正版 解析Python网络爬虫 核心技术 Scrapy框架 分布式爬虫 黑马程序员 Python应用编程丛书 中国铁道出版社...

    商品参数 书名:Python应用编程丛书:解析Python网络爬虫:核心技术.Scrapy框架.分布式爬虫 定价:52.00元 作者:[中国]黑马程序员 出版社:中国铁道出版社 出版日期:2018-0 ...

  8. 黑马程序员_基础测试

    -------android培训.java培训.期待与您交流! ---------- 黑马程序员训练营基础测试题及个人代码(包含思路.步骤和基本注释) 1. 编写程序计算12+22+32+....+1 ...

  9. 黑马程序员_面向对象

    java是面向对象的编程,下面我想通过自己对java的学习,来谈谈对面向对象的理解.      给大家说一个非常熟悉的例子:老张开车去东北.用面向对象的方式考虑这个问题:车,找个司机,然后告诉司机我要 ...

  10. 黑马程序员_集合总篇_基础之重点

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

最新文章

  1. 【控制】《多智能体系统一致性协同演化控制理论与技术》纪良浩老师-第6章-一阶时滞多智能体系统分组一致性
  2. 程序员到项目经理:从内而外的提升不看后悔去吧
  3. 数据库面试题【六、Sql的优化】
  4. PHP写的一个轻量级的DI容器类(转)
  5. c语言 字符串 正序再倒序_新特性解读 | MySQL 8.0 索引特性3 -倒序索引
  6. python中的命令行参数_python学习笔记6:命令行参数
  7. android sqlite alert table,android sqlite数据库操作
  8. typescript索引类型_typescript入门:高级类型
  9. 前端 验证码隐藏怎么实现_Python爬虫教程:200行代码实现一个滑动验证码
  10. 又拍云php表单,又拍云的表单api提交
  11. 无法连接iphone软件更新服务器_上海腾科教育今日分享——提示“无法连接到服务器”的解决办法...
  12. bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)
  13. win8怎么被远程计算机关闭,Win8系统局域网如何远程关机?Win8系统局域网远程关机的方法...
  14. 推荐4个爬虫抓包神器
  15. 微服务架构之监控预警
  16. Several ports (8005, 8080, 8009) required by demo are already in use. The server may already be runn
  17. Java Excel 复制单元格 poi Excel 复制单元格 Java Excel 复制行 Java Excel 复制 sheet 页 poi excel copy
  18. 量化投资发展史上的那些“决定性瞬间”
  19. 重庆大学 计算机组成原理,计算机组成原理课程设计报告重庆大学
  20. python ctypes详解-CTypes

热门文章

  1. 1. 虚拟化Docker
  2. JVM笔记(B站宋红康课件)
  3. 论文记载:FRAP:Learning Phase Competition for Traffic Signal Control
  4. 配好lsd_slam后的使用PTAM工具标定相机
  5. 51,AVR,PIC,MSP430,STM32单片机比较
  6. IIS 热启动设置的方法
  7. SDRAM 控制器(八)——FIFO控制模块
  8. 免焊vga3加6接线图_高清 VGA免焊接头3+6+9 VGA快速接头 免焊公头 3排15针 15针插头...
  9. matlab设计椭圆低通滤波器,基于MATLAB的椭圆数字低通滤波器设计.doc
  10. 南开100题计算机三级数据库,全国计算机三级数据库技术南开100题.doc