• 职责链模式


    职责链模式

    1. 职责链模式(Chain of Responsibility Patterm),又叫责任链模式,为请求创建了一个接收者对象的链(简单示意图)。这种模式对请求的发送者和接收者进行解耦。
    2. 职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
    3. 这种类型的设计模式属于行为型模式

    image-20200731190304694

    • Handler:抽象的处理者,定义了一个处理请求的接口,同时含义另外Handler
    • ConcreteHandlerA, B是具体的处理者,处理它自己负责的请求,可以访 问它的后继者(即下一一个处理者),如果可以处理当前请求,则处理,否则就将该请求交个后继者去处理,从而形成一个职责链

    应用实例:职责链模式解决OA系统采购审批

    1. 应用实例要求
      编写程序完成学校OA系统的采购审批项目:需求
      采购员采购教学器材
      如果金额小于等于5000,由教学主任审批
      如果金额小于等于10000,由院长审批
      如果金额小于等于30000,由副校长审批
      如果金额超过30000以上,由校长审批
    public abstract class Approver {
    
       Approver approver;  //下一个处理者
       String name; // 名字
       
       public Approver(String name) {
          // TODO Auto-generated constructor stub
          this.name = name;
       }
    
       //下一个处理者
       public void setApprover(Approver approver) {
          this.approver = approver;
       }
       
       //处理审批请求的方法,得到一个请求, 处理是子类完成,因此该方法做成抽象
       public abstract void processRequest(PurchaseRequest purchaseRequest);
       
    }
    
    public class CollegeApprover extends Approver {
    
       public CollegeApprover(String name) {
          // TODO Auto-generated constructor stub
          super(name);
       }
       
       @Override
       public void processRequest(PurchaseRequest purchaseRequest) {
          // TODO Auto-generated method stub
          if(purchaseRequest.getPrice() > 5000 && purchaseRequest.getPrice() <= 10000) {
             System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
          }else {
             approver.processRequest(purchaseRequest);
          }
       }
    }
    
    public class DepartmentApprover extends Approver {
    
       
       public DepartmentApprover(String name) {
          // TODO Auto-generated constructor stub
          super(name);
       }
       
       @Override
       public void processRequest(PurchaseRequest purchaseRequest) {
          // TODO Auto-generated method stub
          if(purchaseRequest.getPrice() <= 5000) {
             System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
          }else {
             approver.processRequest(purchaseRequest);
          }
       }
    
    }
    
    public class SchoolMasterApprover extends Approver {
    
    	public SchoolMasterApprover(String name) {
    		// TODO Auto-generated constructor stub
    		super(name);
    	}
    	
    	@Override
    	public void processRequest(PurchaseRequest purchaseRequest) {
    		// TODO Auto-generated method stub
    		if(purchaseRequest.getPrice() > 30000) {
    			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
    		}else {
    			approver.processRequest(purchaseRequest);
    		}
    	}
    }
    
    public class ViceSchoolMasterApprover extends Approver {
    
    	public ViceSchoolMasterApprover(String name) {
    		// TODO Auto-generated constructor stub
    		super(name);
    	}
    	
    	@Override
    	public void processRequest(PurchaseRequest purchaseRequest) {
    		// TODO Auto-generated method stub
    		if(purchaseRequest.getPrice() > 10000 && purchaseRequest.getPrice() <= 30000) {
    			System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
    		}else {
    			approver.processRequest(purchaseRequest);
    		}
    	}
    }
    
    //请求类
    public class PurchaseRequest {
    
       private int type = 0; //请求类型
       private float price = 0.0f; //请求金额
       private int id = 0;
       //构造器
       public PurchaseRequest(int type, float price, int id) {
          this.type = type;
          this.price = price;
          this.id = id;
       }
       public int getType() {
          return type;
       }
       public float getPrice() {
          return price;
       }
       public int getId() {
          return id;
       }
    }
    
    public class Client {
    
       public static void main(String[] args) {
          // TODO Auto-generated method stub
          //创建一个请求
          PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1);
          
          //创建相关的审批人
          DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
          CollegeApprover collegeApprover = new CollegeApprover("李院长");
          ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
          SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");
       
       
          //需要将各个审批级别的下一个设置好 (处理人构成环形: )
          departmentApprover.setApprover(collegeApprover);
          collegeApprover.setApprover(viceSchoolMasterApprover);
          viceSchoolMasterApprover.setApprover(schoolMasterApprover);
          schoolMasterApprover.setApprover(departmentApprover);
          
          
          
          departmentApprover.processRequest(purchaseRequest);
          viceSchoolMasterApprover.processRequest(purchaseRequest);
       }
    
    }
    

    职责链模式细节和注意事项

    1. 将请求和处理分开,实现解耦,提高系统的灵活性
    2. 简化了对象,使对象不需要知道链的结构
    3. 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在setNext(方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
    4. 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
    5. 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、JavaWeb中Tomcat对Encoding的处理、拦截器
  • 相关阅读:
    struts 数据验证指定方法(使用xml文件)
    struts2.0简单页面 (不带拦截器和带拦截器案例)
    tomcat启动流程 和 struts 详解
    代理类Proxy------ WeakHashMap----ReferenceQueue---- Reference
    java 文件上传 struts2.0实现
    java struts xml文件设置----自定义日期转换器(局部,及全局类型转换器类)
    java request,response解析及中文编码 , jsp注释 xml中文编码,getsession()使用方法
    java jsp自定义标签
    Java 通讯录contact
    [Machine Learning for Trading] {ud501} Lesson 3: 01-02 Working with multiple stocks
  • 原文地址:https://www.cnblogs.com/junlinsky/p/14068044.html
Copyright © 2020-2023  润新知