职责者模式
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.实际应用
在实际开发中,经常会出现一个把职责链稍稍变形的用法。在标准的职责链中,一个请求在职责链中传递,只要有一个对象处理了这个请求,就会停止。现在稍稍变一下,改成一个请求在职责链中传递,每个职责对象负责处理请求的某一方面的功能,处理完成后,不是停止,而是继续向下传递请求,当请求通过很多职责对象处理过后,功能也就处理完了,把这样的职责链称为功能链。
职责者模式的本质:分离职责,动态组合。