事物抽象化分析:
项目需求:
用代码演示一个建议的银行业务调度系统,(其实就是叫号系统.)
思路分析:
从名词下手,分析可能需要定义的类:
客户: 普通客户,快速客户,VIP客户.
窗口: 普通窗口,快速窗口,VIP窗口.
用户编号: 普通编号,快速编号,VIP编号(一个编号对应一个客户)
再从行为上下手,具体分析:
客户和编号关联,所以用产生一个编号,对应一个客户.------>编号产生类.
客户类型不同,所以需要上述不同的三个编号产生类.同时要对他们进行调度----->编号管理类.
服务窗口,对应不同的服务类型,存在三种窗口类型,但每种类型有不同.
所以将窗口抽取,类型定义枚举.------>窗口类型枚举,窗口类.
思路分析:
从名词下手,分析可能需要定义的类:
客户: 普通客户,快速客户,VIP客户.
窗口: 普通窗口,快速窗口,VIP窗口.
用户编号: 普通编号,快速编号,VIP编号(一个编号对应一个客户)
再从行为上下手,具体分析:
客户和编号关联,所以用产生一个编号,对应一个客户.------>编号产生类.
客户类型不同,所以需要上述不同的三个编号产生类.同时要对他们进行调度----->编号管理类.
服务窗口,对应不同的服务类型,存在三种窗口类型,但每种类型有不同.
所以将窗口抽取,类型定义枚举.------>窗口类型枚举,窗口类.
下面是跟着老师的步骤一步步来的代码.状态不好,勉强跟上老师思路.还是有很多模糊的地方.想放代码.慢慢消化
服务编号产生类
//定义某个服务编号产生类.
public class Code{
//定义某服务类型下一个号.
private int nextCode = 0;
private List <Integer> listsCode = new LinkedList<Integer>();
//定义取号方法.返回及其中的下一个号.
public synchronized Integer createNewCode(){
listCode.addLast(++nextCode);
return nextCode;
}
//定义分配号方法
public synchronized Integer fetchCode(){
if(listsCode.size()>0){
return(listsCode.removeFist());
}else{
return null;
}
}
}
编号操作类
//定义编号操作机,对应不同服务类型产生同一个的操作机,否则无法同步.(操作包括取号,分配号)
public class CodeMachine{
//设置单例.毕竟应该只有一个
private CodeMachine(){}
private static CodeMachine single = new CodeMachine();
public static CodeMachine getInstance(){
return single;
}
//定义不同服务类型编号的成员属性.代表该机器中可操作的编号类型那个.并定义获取方法.
private Code commonCode = new Code();
private Code expressCode = new Code();
private Code vipCode = new Code();
public Code getCommonCode() {
return commonCode;
}
public Code getExpressCode() {
return expressCode;
}
public Code getVipCode() {
return vipCode;
}
}
服务类型的枚举
//定义枚举类服务类型
public enum CustomerType {
//为了让窗口类只有一个,不同窗口实例对象是通过从枚举中获得某一特定服务类型.
COMMON,EXPRESS,VIP;
public String toString(){
String name = null;
//这里,switch可以用String是从JDK5以后来的新特性.正好方便编程.
switch(this){
case COMMON:
name = "普通";
break;
case EXPRESS:
name = "快速";
break;
case VIP:
name = name();
break;
}
return name;
}
}
服务窗口类
//定义服务窗口类
public class ServiceWindow{
//从定义了的枚举类中,获取服务类型.
private CustomerType type = CustomerType.COMMON;
//定义窗口编号.及其设置方法
private int number = 1;
public void setNumber(int number){
this.number = number;
}
//定义设置,获取服务类型的方法
public CustomerType getType() {
return type;
}
public void setType(CustomerType type) {
this.type = type;
}
//用单线程池来让某个服务类型的窗口,调用该类型服务的方法.
public void start(){
Executors.newSingleThreadExecutor().execute(
new Runnable(){
public void run(){
switch(type){
while(true){
//调用对应类型的服务方法.
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
}
);
}
//定义不同类型服务方法.
//定义普通服务
private void commonService(){
String windowName = "第" + number + "号" + type + "窗口";
System.out.println(windowName + "开始等待普通服务客户");
Integer serviceNumber = CodeMachine.getInstance().getCommonCode().fetchCode();
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 = CodeMachine.getInstance().getExpressCode().fetchCode();
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();
}
}
//定义VIP服务
private void vipService(){
Integer serviceNumber = CodeMachine.getInstance().getVipCode().fetchCode();
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();
}
}
}
测试类
//定义测试类,生成一定数目窗口,一定数目顾客,执行服务.
public class MainClass {
public static void main(String[] args) {
//开放普通窗口并进行实例化
for(int i=1;i<5;i++){
ServiceWindow window = new ServiceWindow();
window.setNumber(i);
window.start();
}
//开放快速窗口
//窗口实例化时,通过调用setType()方法确定了服务类型
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
//开放VIP窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
//普通客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = CodeMachine.getInstance().getCommonCode().createNewCode();
System.out.println(serviceNumber + "号普通客户\t等待服务");
}
},
0,
new Random().nextInt(10)+1,
TimeUnit.SECONDS);
//快速客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = CodeMachine.getInstance().getExpressCode().createNewCdoe();
System.out.println(serviceNumber + "号快速客户\t等待服务");
}
},
0,
(new Random().nextInt(10)+1)*2,
TimeUnit.SECONDS);
//VIP客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = CodeMachine.getInstance().getVipCode().createNewCode();
System.out.println(serviceNumber + "号VIP客户\t等待服务");
}
},
0,
(new Random().nextInt(10)+1)*6,
TimeUnit.SECONDS);
}
}
问题:
其实一直有个不知道怎么实现的想法,我认为服务窗口的服务类型,是体现在客户类型上.应该是由客户的需啊服务类型,决定窗口的最终服务类型.
是不是可以把窗口真实提供的服务,和通常应该提供的服务作为类型抽取出来,想父类引用指向子类对象那样,可以向下兼容的提供服务.
哎,算了,思维比较混了,表达的可能也是比较混乱.
等捋顺了,在跟新.