黑马程序员java笔记之十-----银行管理系统

简介: 模拟实现银行业务调度系统逻辑,具体需求如下:          1.银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。        2. 有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

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

 

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

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

       3 .异步随机生成各种类型的客户,生成各类型用户的概率比例为:   VIP客户 :普通客户 :快速客户 =  1 :6 :3。

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

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

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

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

 

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

 

                      面向对象的分析和设计

一.  客户类型:VIP客户,普通客户,快速客户,异步随机产生各种类型的客户,各客户在其,各类型客户在其对应窗口按顺序依次办理业务。

1.     每一个客户其实就是有银行的一个取号机器产生号码的方法来表示。所以,要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机产生了客户

2.           由于三类客户,每类客户的号码编排都是完全独立的,所以,本系统一共要产生三个号码管理器独享,各自管理一类用户的排队号码。这三个号码管理器同一由一个号码机器进行管理,这个号码机器在真个系统始终只有一个,所以,要被设计成单例

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

 

三、详细设计

                NumberManager和NumberMachine类

A.      NumberManager类

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

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

[java]  view plaincopy
  1. <span style="font-size:18px;">package com.isoftstone.interview.bank;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. //号码机器对象,负责产生客户  
  6. public class NumberManager {  
  7.     private int lastNumber=0;  
  8.     //排队序列  
  9.     private List<Integer> queueNumber=new ArrayList<Integer>();  
  10.     //每次产生一个人加入到list中,现在是第lastNumber为客户开始服务  
  11.     public synchronized int generateNewManager(){  
  12.         queueNumber.add(++lastNumber);  
  13.         return lastNumber;  
  14.     }  
  15.     //取号码  
  16.     public synchronized Integer fetchServiceNumber(){  
  17.         if(queueNumber.size()>0){  
  18.             return (Integer)queueNumber.remove(0);  
  19.         }else{  
  20.             return null;  
  21.         }  
  22.     }  
  23.   
  24. }  
  25.   
  26. </span>  

 

     B.NumMachine类

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

2.       将NumberMachine类设计成单例。

[java]  view plaincopy
  1. <span style="font-size:18px;">package com.isoftstone.interview.bank;  
  2.   
  3.  public class NumberMachine {  
  4.     private NumberManager  commonManager=new NumberManager();  
  5.     private NumberManager  expressManager=new NumberManager();  
  6.     private NumberManager  vipManager=new NumberManager();  
  7.     public NumberManager getCommonManager() {  
  8.         return commonManager;  
  9.     }  
  10.     public NumberManager getExpressManager() {  
  11.         return expressManager;  
  12.     }  
  13.     public NumberManager getVipManager() {  
  14.         return vipManager;  
  15.     }  
  16.     //单例模式,构造方法私有化  
  17.     private  NumberMachine (){}  
  18.     public static NumberMachine getInstance(){  
  19.         return instance;   
  20.     }  
  21.     private static NumberMachine instance=new NumberMachine();  
  22.   
  23. }  
  24. </span>  


  ServiceWindow与CustomerType枚举类

A.  CustomerType枚举类

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

2.       重写toString方法,返回类型的中文名称。这是在后面编写代码时重构出来的,刚开始不用考虑

 

[java]  view plaincopy
  1. <span style="font-size:18px;">package com.isoftstone.interview.bank;  
  2. //枚举类型,覆写toStirng()方法  
  3. public enum CustomerType {  
  4.     COMMON,EXPRESS,VIP;  
  5. @Override  
  6. public String toString() {  
  7.     // TODO Auto-generated method stub  
  8.     switch(this){  
  9.     case COMMON:  
  10.         return "普通";  
  11.     case EXPRESS:  
  12.         return "快速";  
  13.     case VIP:  
  14.         return name();  
  15.     }  
  16.     return null;  
  17. }  
  18. }</span>  

 

 

B.ServiceWindow类

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

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

 

[java]  view plaincopy
  1. <span style="font-size:18px;">package com.isoftstone.interview.bank;  
  2.   
  3. import java.util.Random;  
  4. import java.util.concurrent.Executors;  
  5.   
  6. //窗口依次叫号  
  7. public class ServiceWindow {  
  8.     private int windowNum=1;  
  9.     public void setWindowid(int windowid) {  
  10.         this.windowNum = windowid;  
  11.     }  
  12.     public void setType(CustomerType type) {  
  13.         this.type = type;  
  14.     }  
  15.     //根据类型的不同进行叫号  
  16.     private CustomerType type=CustomerType.COMMON;  
  17.     public void start(){  
  18.       Executors.newSingleThreadExecutor().execute(new Runnable() {  
  19.         public void run() {  
  20.             while(true){  
  21.                 switch (type) {  
  22.                 case COMMON:  
  23.                     commonService();  
  24.                     break;  
  25.                 case EXPRESS:  
  26.                     expressService();  
  27.                     break;  
  28.                 case VIP:  
  29.                     vipService();  
  30.                     break;  
  31.   
  32.                   
  33.                 }  
  34.                   
  35.             }  
  36.         }});}  
  37.         //普通窗口  
  38.         private void commonService() {  
  39.             String windowName="第"+windowNum+"号"+type+"窗口";  
  40.             System.out.println(windowName+"正在获取普通任务");  
  41.             //取票  
  42.             Integer serviceNum=NumberMachine.getInstance().getCommonManager().fetchServiceNumber();  
  43.             if(serviceNum!=null){  
  44.                 System.out.println(windowName+"开始为第"+serviceNum+"号普通客户服务");  
  45.                 int maxRand=Constants.MAX_SERVICE_TIME - Constants.Min_SERVICE_TIME;//最大的服务时间  
  46.                 int serveTime=new Random().nextInt(maxRand)+1+Constants.Min_SERVICE_TIME;  
  47.                 try {  
  48.                     Thread.sleep(serveTime);  
  49.                 } catch (InterruptedException e) {  
  50.                     // TODO Auto-generated catch block  
  51.                     e.printStackTrace();  
  52.                 }  
  53.                   
  54.                 System.out.println(windowName+"完成为第"+serviceNum+"号普通客户服务,总共耗时"  
  55.                                              +serveTime/1000+"秒");  
  56.             }  
  57.             else{  
  58.                 System.out.println(windowName+"没有取得普通任务,正在空闲一秒");  
  59.                 try {  
  60.                     Thread.sleep(1000);  
  61.                 } catch (InterruptedException e) {  
  62.                     // TODO Auto-generated catch block  
  63.                     e.printStackTrace();  
  64.                 }  
  65.             }  
  66.         }  
  67.         //快速窗口  
  68.         private void expressService() {  
  69.             //产生客户的实例,  
  70.             Integer serviceNum=NumberMachine.getInstance().getExpressManager().fetchServiceNumber();  
  71.             String windowName="第"+windowNum+"号"+type+"窗口";  
  72.             System.out.println(windowName+"开始获取快速任务");  
  73.             if(serviceNum!=null){  
  74.                 System.out.println(windowName+"开始为第"+serviceNum+"号快速客户服务");  
  75.                 int serviceTime=Constants.Min_SERVICE_TIME;  
  76.                 try {  
  77.                     Thread.sleep(serviceTime);  
  78.                 } catch (InterruptedException e) {  
  79.                     // TODO Auto-generated catch block  
  80.                     e.printStackTrace();  
  81.                 }  
  82.                 System.out.println(windowName+"完成为第"+serviceNum+"号快速客户服务,总共耗时"+  
  83.       serviceTime/1000+"秒");  
  84.             }  
  85.             else{  
  86.                 System.out.println(windowName+"没有取到快速任务");  
  87.                 //没有任务时,为普通客户服务  
  88.                 commonService();  
  89.           
  90.             }  
  91.         }  
  92.         private void vipService() {  
  93.             String windowName="第"+windowNum+"号"+type+"窗口";  
  94.             System.out.println(windowName+"正在开始获取VIP任务");  
  95.             Integer serviceNum=NumberMachine.getInstance().getVipManager().fetchServiceNumber();  
  96.             if(serviceNum!=null){  
  97.                 System.out.println(windowName+"开始为第"+serviceNum+"号VIP客户服务");  
  98.                 int maxRand=Constants.MAX_SERVICE_TIME-Constants.Min_SERVICE_TIME;//最大的服务时间  
  99.                 int serveTime=new Random().nextInt(maxRand)+1+Constants.Min_SERVICE_TIME;  
  100.                 try {  
  101.                     Thread.sleep(serveTime);  
  102.                 } catch (InterruptedException e) {  
  103.                     // TODO Auto-generated catch block  
  104.                     e.printStackTrace();  
  105.                 }  
  106.                   
  107.               System.out.println(windowName+"完成为第"+serviceNum+"号VIP客户服务,总共耗时"+  
  108.                                          serveTime/1000+"秒");  
  109.             }  
  110.             else{  
  111.                 System.out.println(windowName+"没有取到VIP任务!");//传递此时的type,  
  112.   //所以执行commonService()时还是VIP格式类型还是--->第1号VIP窗口开始为第5号普通客户服务  
  113.                 commonService();  
  114.                   
  115.             }  
  116.         }  
  117.       
  118.     }  
  119.   
  120. </span>  

 MainClass类与Constants类

A.          MainClass类

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

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

 

[java]  view plaincopy
  1. <span style="font-size:18px;">package com.isoftstone.interview.bank;  
  2.   
  3. import java.awt.Window;  
  4. import java.util.concurrent.Executors;  
  5. import java.util.concurrent.TimeUnit;  
  6.   
  7. public class MainClass {  
  8.   
  9.     /** 
  10.      * @param args 
  11.      */  
  12.     public static void main(String[] args) {  
  13.       
  14.         for(int i=1;i<5;i++){  
  15.         //新建四个普通窗口,模拟普通窗口  
  16.         ServiceWindow commonwindow=new ServiceWindow();  
  17.         //设定指定窗口的ID  
  18.         commonwindow.setWindowid(i);  
  19.         commonwindow.start();  
  20.         }  
  21.         //新建一个vip窗口  
  22.         ServiceWindow vipwindow=new ServiceWindow();  
  23.         vipwindow.setType(CustomerType.VIP);  
  24.         vipwindow.start();  
  25.         //快速窗口  
  26.         ServiceWindow expresswindow=new ServiceWindow();  
  27.         expresswindow.setType(CustomerType.EXPRESS);  
  28.         expresswindow.start();  
  29.         //开启三个线程,模拟三个窗口  
  30.         Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  
  31.               
  32.             @Override  
  33.             public void run() {  
  34.                 //产生模拟的新客户  
  35.              Integer number=NumberMachine.getInstance().getExpressManager().generateNewManager();  
  36.              System.out.println("第"+number+"号快速客户在等待服务");  
  37.             }  
  38.         },  
  39.                 0,  
  40.                 Constants.COMMON_CUSTOMER_Time*2,   //执行间隔  
  41.             TimeUnit.SECONDS);  
  42.     Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  
  43.           
  44.         @Override  
  45.         public void run() {  
  46.          Integer number=NumberMachine.getInstance().getVipManager().generateNewManager();  
  47.          System.out.println("第"+number+"号VIP客户在等待服务");  
  48.         }  
  49.     },  
  50.             0,  
  51.             Constants.COMMON_CUSTOMER_Time*6,  
  52.         TimeUnit.SECONDS);  
  53. Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {  
  54.           
  55.         @Override  
  56.         public void run() {  
  57.        Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();  
  58.              System.out.println("第"+number+"号普通客户在等待服务");  
  59.               
  60.         }  
  61.     },  
  62.             0,  
  63.             Constants.COMMON_CUSTOMER_Time,  
  64.         TimeUnit.SECONDS);  
  65.     }  
  66.   
  67. }  
  68. </span>  



 

B.           Contants类

定义三个常量:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTEGVAL_TIME

[java]  view plaincopy
  1. <span style="font-size:18px;">public class Constants {  
  2.     //经常用到的常量  
  3.   public static int MAX_SERVICE_TIME=10000;  
  4.   public static int Min_SERVICE_TIME=1000;  
  5.   public static int COMMON_CUSTOMER_Time=1;  
  6.  }  
  7. </span>  

思考题:

学员的两个面向对象的面试题,用面向对象的方式设计如下情景。

“两块石头磨成一把石刀,石刀可以砍树,砍成木材,木材做成椅子”,  

 * 石头-->(通过KnifeFactory)-->石刀

 * 树-->(通过StoneKnife的cut方法)-->木材-->(ChairFactory的makeChair方法)-->椅子

StoneKnife = KnifeFactory.createKnife(Stone first,Stone second);//KnifeFactory具有制作石刀的方法(createKnife),两块石头磨成石刀

material = StoneKnife.cut(tree);//石刀具有砍树的方法

Chair chair = ChairFactory.makeChair(material);//ChairFactory具有制作椅子的方法makeChair

“球从一根绳子的一段移动到了另一端”,

class Rope {

 private Point start;

 private Point end;

 

 public Rope(Point start, Point end) {

 this.start = start;

 this.end=end;

    }

 public Point nextPoint(Point currentPoint){

 /*

         通过两点一线的数学公式可以计算出当前点的下一个点, 这个细节在设计阶段可以不考虑的问题。

         如果当前点是终止点,则返回null;如果当前点不是线上的店,则抛出异常。

        */

    }

 }

 class Ball{

 private Rope rope;

 private Point currentPoint;

 public Ball(Rope rope,startPoint){

 this.rope=rope;

 this.currentPoint=startPoint;

    }

 public void move(){

       currentPoint=rope.nextPoint(currentPoint);

       System.out.println("小球移动到"+currentPoint);

    }

 }

目录
相关文章
|
1月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
18天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
18天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
21天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
25天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
28 2
|
1月前
|
SQL 存储 Java
面向 Java 程序员的 SQLite 替代品
SQLite 是轻量级数据库,适用于小微型应用,但其对外部数据源支持较弱、无存储过程等问题影响了开发效率。esProc SPL 是一个纯 Java 开发的免费开源工具,支持标准 JDBC 接口,提供丰富的数据源访问、强大的流程控制和高效的数据处理能力,尤其适合 Java 和安卓开发。SPL 代码简洁易懂,支持热切换,可大幅提高开发效率。
|
17天前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
34 0
|
1月前
|
运维 自然语言处理 供应链
Java云HIS医院管理系统源码 病案管理、医保业务、门诊、住院、电子病历编辑器
通过门诊的申请,或者直接住院登记,通过”护士工作站“分配患者,完成后,进入医生患者列表,医生对应开具”长期医嘱“和”临时医嘱“,并在电子病历中,记录病情。病人出院时,停止长期医嘱,开具出院医嘱。进入出院审核,审核医嘱与住院通过后,病人结清缴费,完成出院。
90 3
|
1月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
1月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
13 0
下一篇
DataWorks