Design Patterns Uncovered: The Chain Of Responsibility Pattern

Chain of Responsibility in the Real World

The idea of the Chain Of Responsibility is that it avoids coupling the sender of the request to the receiver, giving more than one object the opportunity to handle the request.  This process of delegation appears quite frequently in the real world where there is one interface for the customer to go through. One example could be a bank, where an application that you send in to the bank branch may be handled by one particular department. Another example is a vending machine, where you can put in any coin, but the coin is passed on to the appropriate receptacle to determine the amount that the coin is worth.  

The Chain of Responsibility Pattern

The Chain of Responsibility is known as a behavioural pattern, as it‘s used to manage algorithms, relationships and responsibilities between objects. The definition of Chain of Responsibility provided in the original Gang of Four book on Design Patterns states: 

Gives more than one object an opportunity to handle a request by linking receiving objects together. 

Chain of Responsibility allows a number of classes to attempt to handle a request, independently of any other object along the chain. Once the request is handled, it completes it‘s journey through the chain.

Let‘s take a look at the diagram definition before we go into more detail.

The Handler defines the interface required to handle request, while the ConcreteHandlers handle requests that they are responsible for.  If the ConcreteHandler cannot handle the request, it passes the request onto it‘s successor, which it maintains a link to.

The objects in the chain just need to know how to forward the request to other objects.  This decoupling is a huge advantage, as you can change the chain at runtime.

Would I Use This Pattern?

This pattern is recommended when either of the following scenarios occur in your application:

  • Multiple objects can handle a request and the handler doesn‘t have to be a specific object
  • A set of objects should be able to handle a request with the handler determined at runtime
  • A request not being handled is an acceptable outcome.

The pattern is used in windows systems to handle events generated from the keyboard or mouse. Exception handling systems also implement this pattern, with the runtime checking if a handler is provided for the exception through the call stack. If no handler is defined, the exception will cause a crash in the program, as it is unhandled.

In JavaEE, the concept of Servlet filters implement the Chain of Responsibility pattern, and may alsodecorate the request to add extra information before the request is handled by a servlet.

So How Does It Work In Java?

Now let‘s take a look at how we might implement the Chain of Responsibility with a code example. Let‘s use an email client as an example. You might set up some rules to move a message into a particular folder depending on who it‘s from. First we‘ll need to create our EmailHandler interface.

//Handler
public interface EmailHandler
{
    //reference to the next handler in the chain
    public void setNext(EmailHandler handler);

    //handle request
    public void handleRequest(Email email);
}

//Now let‘s set up two concrete handlers, one for business mail and one for email originating from Gmail. These handlers pass on the request if it doesn‘t //interest them 

public class BusinessMailHandler implements EmailHandler
{
    private EmailHandler next;

    public void setNext(EmailHandler handler)
    {
        next = handler;
    }

    public void handleRequest(Email email)
    {
        if(!email.getFrom().endsWith("@businessaddress.com")
        {
            next.handleRequest(email);
        }
        else
        {
            //handle request (move to correct folder)
        }

    }    

}
public class GMailHandler implements EmailHandler
{
    private EmailHandler next;

    public void setNext(EmailHandler handler)
    {
        next = handler;
    }

    public void handleRequest(Email email)
    {
        if(!email.getFrom().endsWith("@gmail.com")
        {
            next.handleRequest(email);
        }
        else
        {
            //handle request (move to correct folder)
        }

    }    

}
//Now let‘s set up a client that manages the handlers - this will actually be our EmailProcessor. 

public class EmailProcessor
{
    //maintain a reference to the previous handler so we can add the next one
    private EmailHandler prevHandler;

    public void addHandler(EmailHandler handler)
    {
        if(prevHandler != null)
        {
            prevHandler.setNext(handler);
        }
        prevHandler = handler;
    }

}
//This class allows us to add in new handlers at any stage. Finally, the email client itself uses the EmailProcessor to look after all incoming messages 

//email client 

public class EmailClient
{
    private EmailProcessor processor; 

    public EmailClient()
    {
       createProcessor();

    }

    private void createProcessor()
    {
        processor = new EmailProcessor();
        processor.addHandler(new BusinessMailHandler());
        processor.addHandler(new PersonalMailHandler());
    }

    public void addRule(EmailHandler handler)
    {
       processor.addHandler(handler);
    }

    public void emailReceived(Email email)
    {
        processor.handleRequest(email);
    }

    public static void main(String[] args)
    {

        EmailClient client = new EmailClient();

    }

}

If new rules, for forwarding email to particular folders are added, we can add the handler to our email processor at runtime using the addRule() method in the client.

Watch Out for the Downsides

As with the Observer pattern, Chain of Responsibility can make it difficult to follow through the logic of a particular path in the code at runtime. It‘s also important to note that there is the potential that the request could reach the end of the chain and not be handled at all.

Design Patterns Uncovered: The Chain Of Responsibility Pattern

时间: 2024-10-11 04:19:47

Design Patterns Uncovered: The Chain Of Responsibility Pattern的相关文章

深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)

模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,将请求的发送者和请求的处理者解耦.这就是职责链模式的模式动机. 模式定义职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个

Chain of Responsibility Pattern

1.Chain of Responsibility模式:将可能处理一个请求的对象链接成一个链,并将请求在这个链上传递,直到有对象处理该请求(可能需要提供一个默认处理所有请求的类,例如MFC中的CwinApp类). 2.Chain of Responsibility Pattern 结构图 3.实现 1 #ifndef _HANDLE_H_ 2 #define _HANDLE_H_ 3 4 class Handle 5 { 6 public: 7 virtual ~Handle(); 8 virt

第 17 章 责任链模式【Chain of Responsibility Pattern】

以下内容出自:<<24种设计模式介绍与6大设计原则>> 中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父.既嫁从夫.夫死从子”,也就是说一个女性,在没有结婚的时候要听从于父亲,结了婚后听从于丈夫,丈夫死了还要听儿子的,举个例子来说,一个女的要出去逛街,同样这样的一个请求,在她没有出嫁前她必须征得父亲的同意,出嫁之后必须获得丈夫的许可,那丈夫死了怎么办?一般都是男的比女的死的早,还要问问儿子是否允许自己出去逛街,估计你下边马上要问要是没有儿子怎么办?请示小叔子.侄子

责任链模式 职责链模式 Chain of Responsibility Pattern 行为型 设计模式(十七)

责任链模式(Chain of Responsibility Pattern) 职责链模式 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系 将这些对象连接成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 责任链模式中,每个对象通过持有对下家的引用而链接起来,形成一条链条,串联起来多个处理对象. 在责任链模式中,请求在链上进行传递,直到链上的某一个对象决定处理此请求. 发出这个请求的客户端程序并不知道到底是哪一个对象具体的处理了请求 这使得系统可以在不影响客户

&quot;围观&quot;设计模式(22)--行为型之职责链模式(Chain Of Responsibility Pattern)

责任链模式在面向对象程式设计里是一种软件设计模式,它包含了一些命令对象和一系列的处理对象.每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象.该模式还描述了往该处理链的末尾添加新的处理对象的方法.----WIKIPEDIA 个人的理解 责任链模式用到了链表的数据结构,存在一定的次序性,A->B->C这样的一条链表,在责任链模式中,请求交给A进行处理,如果A处理不了交给B,B如果处理的了进行处理,否则交给C处理,模式的关键在于构建这样的一个链表

设计模式(行为型)之职责链模式(Chain of Responsibility Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之状态模式(State Pattern)>http://blog.csdn.net/yanbober/article/details/45502665 概述 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链

责任链模式(Chain of responsibility pattern)

鲁春利的工作笔记,好记性不如烂笔头 本文出自 "闷葫芦的世界" 博客,请务必保留此出处http://luchunli.blog.51cto.com/2368057/1892886

责任链模式(Chain of Responsibility Pattern)

责任链模式:可以为某个请求创建一个对象链.每个对象依序检查此请求,并对其处理,或者把它传给链中的下一个对象. 责任链上的对象负责处理请求,客户只需要将请求发送到责任链上即可,无需关心处理的细节和请求的传递,所以请求的发送者和接收者解耦了. 类图: 具体例子: 一个Logger日志抽象类,三个具体日志类继承Logger,责任链的顺序是HighestLogger->MiddleLogger->OrdinaryLogger()(顺序是自己定的,可以从高级到低级也可以低级到高级,看具体实现) 为了判断

JAVA设计模式之 职责链模式【Chain of Responsibility Pattern】

一.概述 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止.职责链模式是一种对象行为型模式. 核心在于引入一个抽象处理者类 二.适用场景 请求的链式处理,多个对象可以处理同一请求.但是具体由哪个对象来处理由运行时系统根据条件判断确定. 如请假业务场景: 三.UML类图 四.参与者 1.Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了