设计模式(22)- 职责者模式

职责者模式

1.定义

      使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2.示例代码

      以公司聚餐的餐费申请和差旅费申请为例,说明职责者模式通用框架。

/* 通用的请求对象*/
public class RequestModel {
    /* 表示具体的业务类型*/
    private String type;
    /*通过构造方法把具体的业务类型传递进来*/
    public RequestModel(String type){
       this.type = type;
    }
    public String getType() {
       return type;
    }  
}

/* 定义职责对象的接口*/
public abstract class Handler {
    /* 持有下一个处理请求的对象*/
    protected Handler successor = null;
    /*设置下一个处理请求的对象*/
    public void setSuccessor(Handler successor){
       this.successor = successor;
    }
    /*通用的请求处理方法*/
    public Object handleRequest(RequestModel rm){
       if(successor != null){
           //这个是默认的实现,如果子类不愿意处理这个请求,
           //那就传递到下一个职责对象去处理
           return this.successor.handleRequest(rm);
       }else{
           System.out.println("没有后续处理或者暂时不支持这样的功能处理");
           return false;
       }
    }
}

   

/*封装跟聚餐费用申请业务相关的请求数据*/
public class FeeRequestModel extends RequestModel{
    /* 约定具体的业务类型 */
    public final static String FEE_TYPE = "fee";
    public FeeRequestModel() {
       super(FEE_TYPE);
    }
    /*申请人*/
    private String user;
    /*申请金额*/
    private double fee;
    public String getUser() {
       return user;
    }
    public void setUser(String user) {
       this.user = user;
    }
    public double getFee() {
       return fee;
    }
    public void setFee(double fee) {
       this.fee = fee;
    }
}

/*实现项目经理处理聚餐费用申请的对象*/
public class ProjectManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的项目经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //项目经理的权限比较小,只能在500以内
       if(frm.getFee() < 500){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "项目经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "项目经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //超过500,继续传递给级别更高的人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*实现部门经理处理聚餐费用申请的对象*/
public class DeptManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的部门经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //部门经理的权限比较小,只能在1000以内
       if(frm.getFee() < 1000){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "部门经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "部门经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //超过1000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*实现总经理处理聚餐费用申请的对象*/
public class GeneralManager extends Handler{
    public Object handleRequest(RequestModel rm){
       if(FeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示聚餐费用申请
           return handleFeeRequest(rm);
       }else{
           //其它的总经理暂时不想处理
           return super.handleRequest(rm);
       }
    }
    private Object handleFeeRequest(RequestModel rm) {
       //先把通用的对象造型回来
       FeeRequestModel frm =(FeeRequestModel)rm;
       String str = "";
       //总经理1000以上
       if(frm.getFee() > 1000){
           //为了测试,简单点,只同意小李的
           if("小李".equals(frm.getUser())){
              str = "总经理同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }else{
              //其它人一律不同意
              str = "总经理不同意"+frm.getUser()+"聚餐费用"+frm.getFee()+"元的请求";
           }
           return str;
       }else{
           //后续人处理
           if(this.successor!=null){
              return successor.handleRequest(rm);
           }
       }
       return str;
    }
}

/*客户端调用申请聚餐费用*/
public class Client {
    public static void main(String[] args) {
       //先要组装职责链   
       Handler h1 = new GeneralManager();
       Handler h2 = new DepManager();
       Handler h3 = new ProjectManager();
       h3.setSuccessor(h2);
       h2.setSuccessor(h1);
       //开始测试申请聚餐费用
       FeeRequestModel frm = new FeeRequestModel();
       frm.setFee(300);
       frm.setUser("小李");
       //调用处理
       String ret1 = (String)h3.handleRequest(frm);
       System.out.println("ret1="+ret1);      
       //重新设置申请金额,再调用处理
       frm.setFee(800);    
       h3.handleRequest(frm);
       String ret2 = (String)h3.handleRequest(frm);
       System.out.println("ret2="+ret2);      
       //重新设置申请金额,再调用处理
       frm.setFee(1600);   
       h3.handleRequest(frm);
       String ret3 = (String)h3.handleRequest(frm);
       System.out.println("ret3="+ret3);
    }
}

  

/* 封装跟预支差旅费申请业务相关的请求数据*/
public class PreFeeRequestModel extends RequestModel{
    /* 约定具体的业务类型*/
    public final static String FEE_TYPE = "preFee";
    public PreFeeRequestModel() {
       super(FEE_TYPE);
    }
    /* 申请人*/
    private String user;
    /* 申请金额 */
    private double fee;
    public String getUser() {
       return user;
    }
    public void setUser(String user) {
       this.user = user;
    }
    public double getFee() {
       return fee;
    }
    public void setFee(double fee) {
       this.fee = fee;
    }
}

/**
 * 实现为项目经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的项目经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class ProjectManager2 extends ProjectManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //项目经理的权限比较小,只能在5000以内
       if(frm.getFee() < 5000){
           //工作需要嘛,统统同意
           System.out.println("项目经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //超过5000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/**
 * 实现为部门经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的部门经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class DeptManager2 extends DeptManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //部门经理的权限比较小,只能在10000以内
       if(frm.getFee() < 10000){
           //工作需要嘛,统统同意
           System.out.println("部门经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //超过10000,继续传递给级别更高的人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/**
 * 实现为总经理增加预支差旅费用申请处理的功能的子对象,
 * 现在的总经理既可以处理聚餐费用申请,又可以处理预支差旅费用申请
 */
public class GeneralManager2 extends GeneralManager{
    public Object handleRequest(RequestModel rm){
       if(PreFeeRequestModel.FEE_TYPE.equals(rm.getType())){
           //表示预支差旅费用申请
           return myHandler(rm);
       }else{
           //其它的让父类去处理
           return super.handleRequest(rm);
       }
    }
    private Object myHandler(RequestModel rm) {
       //先把通用的对象造型回来
       PreFeeRequestModel frm = (PreFeeRequestModel)rm;
       //总经理10000以上
       if(frm.getFee() > 10000){
           //工作需要嘛,统统同意
           System.out.println("总经理同意"+frm.getUser()+"预支差旅费用"+frm.getFee()+"元的请求");
           return true;
       }else{
           //后续人处理
           if(this.successor!=null){
              return this.successor.handleRequest(rm);
           }
       }
       return false;
    }
}

/*经理们既可以审批餐费,又可以审批差旅费,客户端调用*/
public class Client {
    public static void main(String[] args) {
       //先要组装职责链   
       Handler h1 = new GeneralManager2();
       Handler h2 = new DepManager2();
       Handler h3 = new ProjectManager2();
       h3.setSuccessor(h2);
       h2.setSuccessor(h1);      
       //开始测试申请聚餐费用
       FeeRequestModel frm = new FeeRequestModel();
       frm.setFee(300);
       frm.setUser("小李");
       //调用处理
       String ret1 = (String)h3.handleRequest(frm);
       System.out.println("ret1="+ret1);   
       //重新设置申请金额,再调用处理
       frm.setFee(800);    
       h3.handleRequest(frm);
       String ret2 = (String)h3.handleRequest(frm);
       System.out.println("ret2="+ret2);   
       //重新设置申请金额,再调用处理
       frm.setFee(1600);   
       h3.handleRequest(frm);
       String ret3 = (String)h3.handleRequest(frm);
       System.out.println("ret3="+ret3);      
       //开始测试申请预支差旅费用
       PreFeeRequestModel pfrm = new PreFeeRequestModel();
       pfrm.setFee(3000);
       pfrm.setUser("小张");
       //调用处理
       h3.handleRequest(pfrm);
       //重新设置申请金额,再调用处理
       pfrm.setFee(6000);
       h3.handleRequest(pfrm);
       //重新设置申请金额,再调用处理
       pfrm.setFee(36000);
       h3.handleRequest(pfrm);
    }
}

 3.实际应用

     在实际开发中,经常会出现一个把职责链稍稍变形的用法。在标准的职责链中,一个请求在职责链中传递,只要有一个对象处理了这个请求,就会停止。现在稍稍变一下,改成一个请求在职责链中传递,每个职责对象负责处理请求的某一方面的功能,处理完成后,不是停止,而是继续向下传递请求,当请求通过很多职责对象处理过后,功能也就处理完了,把这样的职责链称为功能链。

职责者模式的本质:分离职责,动态组合。

猜你喜欢

转载自renhanxiang.iteye.com/blog/2408491