zoukankan      html  css  js  c++  java
  • 黑马程序员——银行业务调度管理系统

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


    当面对一个不太顺手的程序的时候,先不要关心代码,写写自己的头脑中的思维,怎么想就怎么写,写着写着突然就变亮了。


    通过一段时间


    银行业务调度,根据需求做出如下银行业务运转关系图:

    面向对象分析:

    设计源于生活,首先先从我们一次去银行办理业务谈起,我们是怎样完成一次业务办理的呢?首先我们来到银行是取号排队,然后就是等待窗口叫号,叫到号后办理完业务,整个业务就完了

    从编程分析对程序的实现:

    取号器:我们的业务类型有三种业务,那么号码就分为三种号码,设置一个取号的类负责完成取号操作

    号码管理器:取号器里面的号码是怎么产生的呢?号码就是由号码管理器产生的,有三种号码,但仅有一个号码管理器,为了让号码管理器的对象唯一,那么号码管理类就需要采用单列设计模式来完成

    业务窗口:业务窗口分为普通窗口、快速窗口、VIP窗口,这些窗口由窗口类来实现,对于窗口在办理业务的时候都要叫号,对于号码事件,号码数据都存在号码管理器中,窗口需要从号码管理器中获得号码数据

    具体代码实现:

    号码的产生,号码管理器类:

    public class NumberMachine {
    	
    	private NumberMachine(){}
    	private static NumberMachine instance = new NumberMachine();
    	public static NumberMachine getInstance(){
    		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;
    	}
    	
    }

    用户进入银行号码的获取,取号类:

    public class NumberManager {
    	private int lastNumber = 0;
          //使用集合存储生成的号码
    	private List queueNumbers = new ArrayList();
    	public synchronized Integer generateNewNumber(){
    		queueNumbers.add(++lastNumber);
    		return lastNumber;
    	}
    	
    	public synchronized Integer fetchNumber(){
    		//判断当前是否有号码
                if(queueNumbers.size()>0){
    			return (Integer)queueNumbers.remove(0);
    		}else{
    			return null;
    		}
    	}
    }



    窗口的产生窗口类:

    public enum CustomerType {
    	COMMON,EXPRESS,VIP;
    	public String toString(){
    		String name = null;
    		switch(this){
    		case COMMON:
    			name = "普通";
    			break;
    		case EXPRESS:
    			name = "快速";
    			break;
    		case VIP:
    			name = name();
    			break;
    		}
    		return name;
    	}
    }


    窗口进行有序工作的窗口功能实现类:

    没有把VIP窗口和快速窗口做成子类,是因为实际业务中的普通窗口可以随时被设置为VIP窗口和快速窗口。

    为了然代码数量少一点,便于阅读将张老师的提供的代码代码中一些打印语句省略

    public class ServiceWindow {
    	private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
    	private CustomerType type = CustomerType.COMMON;
    	private int number = 1;
          
    	public CustomerType getType() {
    		return type;
    	}
    
    	public void setType(CustomerType type) {
    		this.type = type;
    	}
    	
    	public void setNumber(int number){
    		this.number = number;
    	}
    	
    	public void start(){
    		Executors.newSingleThreadExecutor().execute(
    				new Runnable(){
    					public void run(){
    						//下面这种写法的运行效率低,最好是把while放在case下面
    						while(true){
    							switch(type){
    								case COMMON:
    									commonService();
    									break;
    								case EXPRESS:
    									expressService();
    									break;
    								case VIP:
    									vipService();
    									break;
    							}
    						}
    					}
    				}
    		);
    	}
    	
    	private void commonService(){		
    		//开始获取普通任务
    		Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();		
    		if(serviceNumber != null ){
    			//开始为客户服务	
    			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();
    			}	
    		}else{
    			//没有取到普通任务,并等待		
    			try {
    				Thread.sleep(1000);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}				
    		}
    	}
    	
    	private void expressService(){
    		Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();	
    		if(serviceNumber !=null){			
    			int serviceTime = Constants.MIN_SERVICE_TIME;
    			try {
    				Thread.sleep(serviceTime);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}			
    		}else{				
    			commonService();
    		}
    	}
    	
    	private void vipService(){
    		Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber();	
    		//开始获取VIP任务			
    		if(serviceNumber !=null){
    			//获取到VIP任务并为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();
    			}				
    		}else{
    			//没有取到VIP任务,并获取快速窗口任务				
    			commonService();
    		}	
    	}
    }

    常量放置的类:

    public class Constants {
    	public static int MAX_SERVICE_TIME = 10000; //10秒!
    	public static int MIN_SERVICE_TIME = 1000; //1秒!
    	
    	//产生一个客户的时间
    	public static int COMMON_CUSTOMER_INTERVAL_TIME = 1; 	
    }
    

    代码运行的主类:

    public class MainClass {
    	
    	private static Logger logger = Logger.getLogger("cn.itcast.bankqueue");
    	public static void main(String[] args) {
    		//产生4个普通窗口
    		for(int i=1;i<5;i++){
    			ServiceWindow window =  new ServiceWindow();
    			window.setNumber(i);
    			window.start();
    		}
    	
    		//产生1个快速窗口
    		ServiceWindow expressWindow =  new ServiceWindow();
    		expressWindow.setType(CustomerType.EXPRESS);
    		expressWindow.start();
    		
    		//产生1个VIP窗口		
    		ServiceWindow vipWindow =  new ServiceWindow();
    		vipWindow.setType(CustomerType.VIP);
    		vipWindow.start();		
    		
    		//普通客户拿号
    		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
    				new Runnable(){
    					public void run(){
    						Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();					
    					}
    				},
    				0,
    				Constants.COMMON_CUSTOMER_INTERVAL_TIME, 
    				TimeUnit.SECONDS);
    		
    		//快速客户拿号
    		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
    				new Runnable(){
    					public void run(){
    						Integer serviceNumber = NumberMachine.getInstance().getExpressManager().generateNewNumber();
    					}
    				},
    				0,
    				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, 
    				TimeUnit.SECONDS);
    		
    		//VIP客户拿号
    		Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
    				new Runnable(){
    					public void run(){
    						Integer serviceNumber = NumberMachine.getInstance().getVipManager().generateNewNumber();
    					}
    				},
    				0,
    				Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, 
    				TimeUnit.SECONDS);
    	}
    }




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

    用心-细心-专心-决心 学习就像爬大山,一步一步向前走 -态度决定高度-
  • 相关阅读:
    ubuntu(linux)虚拟主机部署桌面,使用window链接
    扫描shader
    Android Studio快捷键
    eclipse取消空格、等号、分号自动录入
    Libgdx学习记录28——创建Desktop程序
    设计模式19——代理模式
    设计模式18——模板方法
    设计模式17——解释器模式
    设计模式16——工厂模式
    设计模式15——外观模式
  • 原文地址:https://www.cnblogs.com/xianyou-liang/p/8503355.html
Copyright © 2011-2022 走看看