职责者模式
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.实际应用
在实际开发中,经常会出现一个把职责链稍稍变形的用法。在标准的职责链中,一个请求在职责链中传递,只要有一个对象处理了这个请求,就会停止。现在稍稍变一下,改成一个请求在职责链中传递,每个职责对象负责处理请求的某一方面的功能,处理完成后,不是停止,而是继续向下传递请求,当请求通过很多职责对象处理过后,功能也就处理完了,把这样的职责链称为功能链。
职责者模式的本质:分离职责,动态组合。
相关推荐
设计模式-职责链模式(讲解及其实现代码)
职责链模式 设计模式 Chain of Responsibility 若有问题望指出。
1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...
设计模式-建造者模式,该模式涉及产品,构造者,指挥者、调用者等几个角色,职责明确,在实际项目中使用得比较多。
设计模式之职责链模式的代码详解,简单明了的将模式思想以代码编写出来,常用的设计模式
1.2 Smalltalk MVC中的设计模式 1.3 描述设计模式 1.4 设计模式的编目 1.5 组织编目 1.6 设计模式怎样解决设计问题 1.7 怎样选择设计模式 1.8 怎样使用设计模式 第二章 实例研究:设计一个文档编辑器 2.1 设计问题...
本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。为什么呢?一旦你熟悉了装饰者的技巧...——《Head First 设计模式》
设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。 2.结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 4.行为型模式:...
Java代码积累:并发 设计模式 数据结构 使用容器 实用 类 基础知识 并发性 演示线程的生命周期 生产者-消费者 设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者...
《C++20设计模式》学习笔记-第13章职责链模式-配套代码
参考<大话设计模式>,采用python书写的模板类。职责链模式。
c++设计模式-结构型模式-装饰器模式;QT工程;c++简单源码; 装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
创建模式: ...设计模式之Chain of Responsibility(职责链) 设计模式之Command 设计模式之State 设计模式之Strategy(策略) 设计模式之Mediator(中介者) 设计模式之Interpreter(解释器) 设计模式之Visitor
C#23种设计模式样例代码和UML图等 创建型模式(抽象工厂模式、工厂方法模式、单例模式、建造者模式、原型模式); 行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 ...
Java 23种设计模式17职责链模式.pdf
设计模式(22)-Strategy Pattern 211 一、 策略(Strategy)模式 211 二、 策略模式的结构 212 三、 示意性源代码 212 四、 何时使用何种具体策略角色 215 五、 一个实际应用策略模式的例子 215 六、 在什么情况下...
整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法可以作为后来者的榜样。如果要知道怎样恰当定义和描述设计模式,我们应该可以从他们那儿获得启发”--steve...
设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计...
设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂...
《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,让读者能系统、完整、准确地掌握每个模式,...