设计模式13 - 职责链Chain-Of-Responsibility

来源:互联网 发布:陈一发淘宝店叫什么 编辑:程序博客网 时间:2024/06/13 22:28


Decoupling is one of the prominent mantras in software engineering. Chain of responsibility helps to decouple sender of a request and receiver of the request with some trade-offs. Chain of responsibility is a design pattern where a sender sends a request to a chain of objects, where the objects in the chain decide themselves who to honor the request. If an object in the chain decides not to serve the request, it forwards the request to the next object in the chain.

Responsibility is outsourced. In a chain of objects, the responsibility of deciding who to serve the request is left to the objects participating in the chains. It is similar to ‘passing the question in a quiz scenario’. When the quiz master asks a question to a person, if he doesn’t knows the answer, he passes the question to next person and so on. When one person answers the question, the passing flow stops. Sometimes, the passing might reach the last person and still nobody gives the answer.

Welcome to behavioral design patterns. This is the first tutorial in behavioral category of our famous design pattern series.

Highlights of Chain of Responsibility

  • Sender will not know which object in the chain will serve its request.
  • Every node in chain will have the responsibility to decide, if they can serve the request.
  • If node decides to forward the request, it should be capable of choosing the next node and forward it.
  • There is a possibility where none of the node may serve the request.

Problems in Chain of Responsibility

There may be scenarios where a node is capable of solving the request but may not get a chance for it. Though there is a candidate who can solve the problem, but since nobody forwarded the request to it, it was not given a chance to serve and final result is the request goes unattended failure. This happens because of improper chain sequence. A chain sequence may not be suitable for all scenarios.

In object oriented design generally, every object is responsible for all its behaviour. Behaviour of an object is not transferred to other objects and is enclosed within itself. In chain of responsibility, some percentage of behaviour is offloaded to third party objects.

Chain of Responsibility Example

When thinking about nice examples for chain of responsibility pattern following list came to my mind. Coin sorting machine, ATM money dispenser, Servlet Filter and finally java’s own Exception Handling mechanism. We know exception handling better than anybody else and we are daily living with it. This qualifies as the best example for chain of responsibility.

We may have sequence of exceptions listed in catch statements and when there is an exception thrown, the catch list is scanned one by one from top. If first exception in catch can handle it the job is done, else the responsibility is moved to next in line and so on till it reaches finally block if we have one.

UML Diagram for Chain of Responsibility

Example Java Code

Following example code gives a sample implementation of chain of responsibility.

Chain.java

This is the interface that acts as a chain link.

public interface Chain {    void setNext(Chain nextInChain);    void process(Number request);                                                                             }

Number.java

This class is the request object.

public class Number {    private int number;    public Number(int number) {        this.number = number;    }    public int getNumber() {        return number;                                                                                            }}

NegativeProcessor.java

This class is a link in chain series.

public class NegativeProcessor implements Chain {    private Chain nextInChain;    public void setNext(Chain c) {        nextInChain = c;    }    public void process(Number request) {        if (request.getNumber() < 0) {            System.out.println("NegativeProcess: " + request.getNumber());        } else {            nextInChain.process(request);                                                                             }    }}

ZeroProcessor.java

This class is another link in chain series.

public class ZeroProcessor implements Chain {    private Chain nextInChain;    public void setNext(Chain c) {        nextInChain = c;    }    public void process(Number request) {        if (request.getNumber() == 0) {            System.out.println("ZeroProcessor: " + request.getNumber());        } else {            nextInChain.process(request);                                                                             }    }}

PositiveProcessor.java

This class is another link in chain series.

public class PositiveProcessor implements Chain {    private Chain nextInChain;    public void setNext(Chain c) {        nextInChain = c;    }    public void process(Number request) {        if (request.getNumber() > 0) {            System.out.println("PositiveProcess: " + request.getNumber());                                            } else {            nextInChain.process(request);        }    }}

TestChain.java

This class configures the chain of responsibility and executes it.

public class TestChain {    public static void main(String[] args) {        // Configure Chain of Responsibility        Chain c1 = new NegativeProcessor();        Chain c2 = new ZeroProcessor();        Chain c3 = new PositiveProcessor();        c1.setNext(c2);        c2.setNext(c3);        //Calling Chain of Responsibility        c1.process(new Number(99));        c1.process(new Number(-30));        c1.process(new Number(0));        c1.process(new Number(100));                                                                              }}

Output for chain of responsibility example










原创粉丝点击