`
wangwengcn
  • 浏览: 176260 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

10.责任链模式(Chain of Responsibility)

阅读更多

1.定义:

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

 

2.通用代码

这个模式很简单,也许看完通用代码就能理解了:

package _10ChainOfResponsibility;

public abstract class Handler {
	
	private Handler nextHandler;
	
	public final void service(String request)
	{
		// 判断自己能否提供服务,如果不能,将任务提交给下一个处理者
		if(this.canIService())
		{
			this.realService();
		}else{
			if(null != nextHandler)
			{
				// 将任务提交给下一个处理者
				nextHandler.service(request);
			}else{
				// 我没权限处理,又找不到我的上级,不知道该怎么办了
			}
		}
	}

	public void setNextHandler(Handler nextHandler) {
		this.nextHandler = nextHandler;
	}
	
	// 根据一定条件判断我能否提供服务
	protected abstract boolean canIService();
	// 真正的服务方法
	protected abstract void realService();
}

 

3.责任链模式的两个角色

  • 抽象处理者(Handler)角色: 定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。Handler类的聚合关系给出了具体子类对下家的 引用,抽象方法service()规范了子类处理请求的操作。
  • 具体处理者(ConcreteHandler)角色: 具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

4.使用场景

来考虑这样一个功能:申请聚餐费用的管理。
很多公司都是这样的福利,就是项目组或者是部门可以向公司申请一些聚餐费用,用于组织项目组成员或者是部门成员进行聚餐活动。
申请聚餐费用的大致流程一般是:由申请人先填写申请单,然后交给领导审批,如果申请批准下来,领导会通知申请人审批通过,然后申请人去财务领取费用,如果没有批准下来,领导会通知申请人审批未通过,此事也就此作罢。
不同级别的领导,对于审批的额度是不一样的,比如,项目经理只能审批500元以内的申请;部门经理能审批1000元以内的申请;而总经理可以审核任意额度的申请。
也就是说,当某人提出聚餐费用申请的请求后,该请求会经由项目经理、部门经理、总经理之中的某一位领导来进行相应的处理,但是提出申请的人并不知道最终会由谁来处理他的请求,一般申请人是把自己的申请提交给项目经理,或许最后是由总经理来处理他的请求。
可以使用责任链模式来实现上述功能:当某人提出聚餐费用申请的请求后,该请求会在 项目经理—〉部门经理—〉总经理 这样一条领导处理链上进行传递,发出请求的人并不知道谁会来处理他的请求,每个领导会根据自己的职责范围,来判断是处理请求还是把请求交给更高级别的领导,只要有领导处理了,传递就结束了。
需要把每位领导的处理独立出来,实现成单独的职责处理对象,然后为它们提供一个公共的、抽象的父职责对象,这样就可以在客户端来动态地组合职责链,实现不同的功能要求了。

 

下面来看用责任链模式实现的上述功能:

 

package _10ChainOfResponsibility;

public abstract class FeeHandler {

private FeeHandler nextHandler;
	
	public final boolean handleFeeRequest(int fee)
	{
		// 判断自己是否有资格审批,如果不能,将任务提交给上级处理
		if(this.canIService(fee))
		{
			this.realService(fee);
		}else{
			if(null != nextHandler)
			{
				// 将任务提交给上级
				return nextHandler.handleFeeRequest(fee);
			}
		}
		return false;
	}

	public void setNextHandler(FeeHandler nextHandler) {
		this.nextHandler = nextHandler;
	}
	
	// 根据金额判断我能否审批
	protected abstract boolean canIService(int fee);
	
	// 真正的审批方法
	protected abstract void realService(int fee);
}
 
package _10ChainOfResponsibility;
//项目经理
public class ProjectManagerHandler extends FeeHandler {

	@Override
	protected boolean canIService(int fee) {
		if(fee > 500)
		{
			System.out.println(fee+"元,项目经理没权限审批");
			return false;
		}
		return true;
	}

	@Override
	protected void realService(int fee) {
		System.out.println(fee+"元,项目经理批了");
	}

}
 
package _10ChainOfResponsibility;
// 部门经理
public class DeptManagerHandler extends FeeHandler {

	@Override
	protected boolean canIService(int fee) {
		if(fee > 1000)
		{
			System.out.println(fee+"元,部门经理没权限审批");
			return false;
		}
		return true;
	}

	@Override
	protected void realService(int fee) {
		System.out.println(fee+"元,部门经理批了");
	}

}
 
package _10ChainOfResponsibility;
//总经理
public class GeneralManagerHandler extends FeeHandler {

	@Override
	protected boolean canIService(int fee) {
		// 总经理就是牛,多少金额都能批
		return true;
	}

	@Override
	protected void realService(int fee) {
		System.out.println(fee+"元,总经理批了");
	}

}
 
package _10ChainOfResponsibility;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ProjectManagerHandler pmh = new ProjectManagerHandler();
		DeptManagerHandler dmh = new DeptManagerHandler();
		GeneralManagerHandler gmh = new GeneralManagerHandler();
		
		pmh.setNextHandler(dmh);
		dmh.setNextHandler(gmh);
		
		System.out.println("张三找PM报销餐费300");
		pmh.handleFeeRequest(300);
		System.out.println("张三找PM报销餐费600");
		pmh.handleFeeRequest(600);
		System.out.println("张三找PM报销餐费2000");
		pmh.handleFeeRequest(2000);
		
	}

}
 
Client输出:
张三找PM报销餐费300
300元,项目经理批了
张三找PM报销餐费600
600元,项目经理没权限审批
600元,部门经理批了
张三找PM报销餐费2000
2000元,项目经理没权限审批
2000元,部门经理没权限审批
2000元,总经理批了

 

5.纯的与不纯的责任链模式

一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。有些人认为不纯的责任链根本不是责任链模式,这也许是有道理的。但是在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。

 

6.责任链模式的优点

责任链模式非常显著的优点是将请求和处理分开。请求者可以不知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。

 

7.责任链模式的缺点

责任链模式有两个非常显著的缺点:

  • 一是性能问题,每个请求都要从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。
  • 二是调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑比较复杂。

8.责任链模式的注意事项

责任链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经超过了其阀值,超过则不允许该链建立,避免无意识地破坏系统性能。

 

9.实际使用示例

众所周知Tomcat中的Filter就是使用了责任链模式,创建一个Filter除了要在web.xml文件中做相应配置外,还需要实现javax.servlet.Filter接口。

 

public class TestFilter implements Filter{

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        
        chain.doFilter(request, response);
    }

    public void destroy() {
    }

    public void init(FilterConfig filterConfig) throws ServletException {
    }

}
 
分享到:
评论

相关推荐

    设计模式C++学习之责任链模式(Chain of Responsibility)

    责任链模式(Chain of Responsibility)是一种行为设计模式,它允许将请求沿着处理者对象的链进行传递,直到某个对象能够处理这个请求。这种模式的主要优点是解耦了发送者和接收者之间的关系,使得系统更加灵活,...

    java设计模式之责任链(chain of responsibility)

    责任链(Chain of Responsibility)模式是一种行为设计模式,它允许我们向对象链中传递请求,让每个对象决定是否处理这个请求。在Java中,这种模式常用于事件处理、日志系统或者权限控制等场景,其核心思想是将处理...

    c++-设计模式之责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将请求的发送者和接收者解耦。通过将请求沿着处理链传递,直到有对象处理该请求为止,这种模式避免了请求发送者与具体处理者之间的紧...

    Chain of Responsibility模式

    这个模式的主要目的是允许在对象之间传递请求,同时避免将接收者硬编码到发送者中,使得多个对象有机会处理一个请求,形成一个责任链。 ### 一、模式概念 在Chain of Responsibility模式中,请求的发送者将请求...

    Chain of Responsibility 职责链模式

    C#面向对象设计模式 Chain of Responsibility 职责链模式 视频讲座下载

    【Java设计模式】(3)责任链Chain of Responsibility

    **Java设计模式——责任链(Chain of Responsibility)** 在软件工程中,设计模式是一种解决常见问题的可重用解决方案。责任链模式是行为设计模式之一,它的主要思想是将请求的发送者和接收者解耦,通过将多个处理...

    (行为型模式) Chain Of Responsibility 职责链模式

    C#面向对象设计模式 (行为型模式) Chain Of Responsibility 职责链模式 视频讲座下载

    chain of responsibility.pptx

    责任链模式(Chain of Responsibility Pattern)是一种常见的行为模式。 使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象串成一条链,并沿着这条链一直传递该请求,直到有...

    Chain Of Responsibility模式

    Chain of Responsibility(责任链)模式是一种行为设计模式,它允许将请求沿着处理者对象的链进行发送,每个对象都可以处理请求或将其传递给链中的下一个对象。这种模式常用于事件处理或者命令的执行流程,使得多个...

    设计模式 - Chain of Responsibility Pattern(责任链模式)

    NULL 博文链接:https://linkcqu.iteye.com/blog/355806

    chain-of-responsibility-demo 责任链模式demo

    在这个`chain-of-responsibility-demo`中,我们可以预期找到一个实际应用了责任链模式的代码示例。通常,它会包含以下关键组件: 1. **Handler**(处理器):这是责任链中的基本单元,每个处理器都实现了处理请求的...

    chain of responsibility 职责链模式(行为模式)

    职责链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求的发送者和接收者解耦,使得多个对象都有可能处理一个请求,而无需显式指定接收者。在这个模式中,请求沿着一个处理者链进行传递,...

    C#面向对象设计模式纵横谈(20):(行为型模式) Chain Of Responsibility 职责链模式

    职责链模式(Chain of Responsibility)是一种行为型设计模式,它允许将请求沿着处理者对象的链进行传递,直到某个对象能够处理这个请求。在C#中,职责链模式的应用可以帮助我们构建灵活、可扩展的系统,减少对象...

    Java设计模式之责任链模式(Chain of Responsibility模式)介绍

    责任链模式(Chain of Responsibility,CoR)是一种行为设计模式,它允许将请求沿着处理者对象的链式结构进行传递,直到某个对象处理这个请求。每个处理者对象都包含对下一个处理者的引用,如果当前处理者无法处理...

    C#面向对象设计模式纵横谈(14):Chain of Responsibility 职责链模式(行为型模式) (Level 300)

    职责链模式(Chain of Responsibility)是一种行为型设计模式,它允许你将请求沿着处理者对象的链进行传递,直到某个对象处理该请求。在C#编程中,职责链模式能够帮助我们实现一种松耦合的架构,使得请求的发送者和...

    C#面向对象设计模式纵横谈(14):Chain of Responsibility 职责链模式(行为型模式)

    ### C#面向对象设计模式纵横谈(14):Chain of Responsibility 职责链模式(行为型模式) #### 概述 在本篇文章中,我们将深入探讨C#中的Chain of Responsibility(职责链)模式,这是行为型设计模式的一种。虽然标题...

    责任链模式_javaDemo

    责任链模式(Chain of Responsibility)的目标是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 在处理用户的...

    C#设计模式_设计模式_C#_

    创建型: 1. 单件模式(Singleton ... 职责链模式(Chain of Responsibility Pattern) 20. 备忘录模式(Memento Pattern) 21. 策略模式(Strategy Pattern) 22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    04-Chain Of Responsibility.rar

    《责任链模式:构建灵活的处理流程》 责任链模式是一种行为设计模式,它允许将请求沿着处理者链进行发送,每个处理者都可以选择处理请求或将其传递给链中的下一个处理者。这种模式使得系统可以灵活地添加、删除或...

Global site tag (gtag.js) - Google Analytics