银行业务调度系统I

来源:互联网 发布:阿里妈妈是淘宝客吗 编辑:程序博客网 时间:2024/05/10 06:46

银行业务调度系统

题目要求

面向对象整体思路分析

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

1.    题目要求

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

1). 银行窗口的分类

银行内有6个业务窗口:分三类窗口

[1]. 1~4号窗口为普通窗口

[2]. 5号窗口为快速窗口

[3]. 6号窗口为VIP窗口。

2). 客户的种类和比例

[1]. 客户的种类

有三种对应类型的客户

{1}. VIP客户

{2}. 普通客户

{3}. 快速客户 (办理如交水电费、电话费之类业务的客户)

[2]. 客户的比例

{1}. 异步随机生成各种类型的客户

{2}. 生成各类型用户的概率比例为

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

3). 客户办理业务的时间规定

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

注意1】各类型客户在其对应窗口按顺序依次办理业务

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

4). VIP窗口和快速业务窗口的额外要求

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

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

2.    面向对象整体思路分析

这次从流程的整个过程进行分析出整个系统的大致轮廓

1). 流程模拟

(1). 文字叙述

[1]. 这个过程用文字叙述是这样的:

无限多的客户到号码机不停地取属于自己类型的号码。6个业务窗口都不停滴在为指定号码对应的客户进行服务。

[2]. 写成单线程的伪代码或者文字代码 -----代码基本上分成两块,如下图


第一块主要就是号码机不停滴为客户生成各种类型的号码。生成号码之后,客户等待一直在服务的服务窗口叫道自己的号码并被服务。【单线程

(2). 从给出的单线程代码块提取类的信息

[1]. 提取第一部分的类和对象

注意:不同的类型客户取到不同类型号码

{1}. 显式提取

用语言描述出来的对象,文字中的“客户”、“号码机”和“号码”,这样就是非常明显的要提取出来的类,并这句话对应的代码用到了这个类的实例,所以一定要对这三个类的实例进行实例化(new)。

{1}1. 为了后面说明方便,分别将“客户”、“号码机”和“号码”的类名取名为Customer、NumberMachine和Number这三个类

{1}2. 注意窗口服务的对象是持有号码的顾客。所以窗口服务的对象是“号码”。没有号码的客户不能从窗口获取服务。所以单纯的“客户”类意义不大。

简化结果】保留下来的类是NumberMachine和Number,Customer类是可以丢弃的。

{1}3. 号码机(NumberMachine类的实例)在整个银行只有一个,因此一定要把NumberMachine类进行单例模式化处理。

{2}. 隐式提取【依据功能】

{2}1. 根据需求“不同类型的客户从一个号码机取出不同类型号码”说明号码机内部一定不止一个号码管理器。这样号码机仅仅是从不同类型号码管理器取出不同类型的号码。

{2}2. 这里面有三种类型的客户(三种类型的号码),那就应该有三种类型的号码管理器

结论】为“号码管理器”中定义类“NumberManager”。这里面一定是三个NumberManager类的实例。

{2}3. 这里面是号码机NumberMachine用到了“向各个号码管理器获取号码”这个功能,也就是调用一个方法所以一定是先有来自某个类的对象,才能调用这个类对象的方法。由于已经抽象出来了号码管理器类,所以这个地方一定要new出来三个号码管理器类的实例

{3}. 图示


[2]. 提取第二部分的类和对象

{1}. 显式提取

用语言描述出来的对象,文字中的六个“服务窗口”,这样就是非常明显的要提取出来的类,并这句话对应的代码用到了这个类的实例,所以一定要对这个类进行实例化(new)。

命名】将服务窗口对应的类取名为“ServiceWindow”类

{2}. 隐式提取-----没有

{3}. 图示


(3). 细化给出的文字伪代码

[1]. 第一块代码细化

{1}. 图示


{2}.三个NumberManager实例中一定是能够直接操作到前面定义1000+个号码实例,所以NumberMachine里面非常有可能直接获取号码Number实例组成的集合。

可能性I:这1000+个号码实例作为共享数据被直接使用-----枚举成员的特点 publicstatic final  ---- 但是号码并不是固定的,所以枚举这个想法不成立

可能性II:NumberManager类直接聚合一个List<Number> queryNumber ----私有数据的思路

可能性III:直接NumberManager一样直接new出来。如果选择直接new Number出来,那么NumberManager这个生成号码的功能就直接需要接受一个List<Number>来传入这个1000+个号码,很麻烦。

结论】号码的实例集合一定是聚合在NumberManager的实例中。每一种号码管理器都有自己类型的号码集合。

*********************************

{3}.唯一的NumberMachine实例中一定是能够3个号码管理器的实例的数据,因为号码机要控制从哪个号码管理器中取出号码发给客户。所以NumberMachine里面非常有可能直接获取号码Number实例组成的集合。

可能性I:这3个号码管理器作为共享数据被直接使用-----枚举成员的特点 publicstatic final  ---- 固定,可以共享

可能性II:NumberMachine类直接聚合一个List<NumberManager> numberManagers----私有数据的思路【集合中只哟三个数据】---- 可用

结论】选用私有数据方案。由于直接给出类三种号码管理器,所以这里面就不直接使用List,而是直接给出三个号码管理器成员。这样的做法和集合是一样的。只不过为集合中的每一个成员都命名为commonManager、expressManager和VIPManager三个成员。

[2]. 第二块代码细化

{1}. 图示


{2}.ServiceWindow类不能再次聚合三个NumberManager,这是因为NumberManager只存在三个,并且被聚合到NumberMachine的实例中(单利)。因此要获得对应类型的号码,就必须通过NumberMachine类型的唯一的实例来获取对应类型的NumberManager。再通过这个实例的获取对应类型的号码。再通过Thread.sleep()方法进行服务的模拟。

(4). 这个单线程的伪代码

[1]. 整合一下,看看是否可以达到理想的运行效果


[2]. 单线程存在的问题

{1}. 当主线程运行到一个普通号码机以无限循环的方式生成号码的循环的时候,就没有办法运行下面的无限循环代码块。并且号码管理器需要同时运行,产生不同类型的号码。

{2}. 下面的6个窗口必须同时运行以保证一起为客户服务。

{3}. 总的线程图如下:


{4}. 检查多线程运行的时候,有没有共享数据存在?有的话,别忘记同步!!!!

注意到:以CommonManager号码管理器给出的号码为例,CommonManager里面聚合了普通用户的所有号码。前面的线程使用这个号码管理器生成号码,后面四个Common窗口就使用这个CommonManager对象获取当前的号码。当前号码就成了共享数据,所以对应的方法“生成号码”和“获取Common类型的号码”这两个方法就必须设置成同步的方法。这样调用这两个方法的对象只要保证是一个(同步的锁对象)----commonManager对象,那么多线程在访问这个commonManager对象的方法的时候,就能够实现同步了,因为锁对象就是一个,commonManager对象。-----CommonManager类中的方法必须全部是同步的方法

注意做到这种程度之后,就可以将各个功能嵌入到每个模块进行分析了

总结】无论使用共享变量的方法(全局常量,单例模式,枚举成员变量),还是私有变量(聚合作为私有的成员变量),还是直接传入对象作为方法的实际参数只要是能够获取到需要的对象所需要的其他对象的数据,就是目的。实现之后,再重新优

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

 

原创粉丝点击