黑马程序员_银行业务调度系统
来源:互联网 发布:河钢唐钢 云计算 编辑:程序博客网 时间:2024/06/08 03:00
一、需求分析:
Ø 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
Ø 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
Ø 异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户:普通客户:快速客户 = 1:6:3。
Ø 客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
Ø 各类型客户在其对应窗口按顺序依次办理业务。
Ø 当VIP(6号)窗口和快速业务(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);
}
}
五、经验总结
------------------------------------------------------------------------------------
此案例的成功之处在于模块职责分工得很明确,各模块分别实现属于自己功能,然后再将各个模块组合成一个系统。最大的成功就是用面向对象的思惟来为模块分配职责,如果职责分配不清的话,那么各个模块之间的偶合度大,会给编码带来麻烦。
当在做一个项目时,不能一拿到需求就要去写代码,而是应该把需求做详细的分析之后,把项目的各个模块职责划分清楚,在思想上清析了,写起代码来时,才会得心应手,在对项目似懂非懂的情况下是不能去写代码的。
当我们在分析一个项目时,一定要以面向对象的思惟去考虑问,却不能想这模块怎么做,那模块怎么做,而是从全局性出发,考虑的应该是这模块分为几个对象,分别提供是什么样的功能,为哪些模块提供服务等。
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- 黑马程序员_银行业务调度系统
- Java——用户界面的布局
- spoj687
- gallery 循环播放
- 对malloc的返回值应该如何转型
- 5.1环型链表概述
- 黑马程序员_银行业务调度系统
- 如何实现在屏幕上有漂亮的刀光效果并有星星环绕
- Faster, Higher, Stronger
- oracle主键自动增长的设置
- PAT中文版1004.成绩排名
- poj 2726
- javascript css html笔记
- arm-linux-objdump
- MySQL教程