노현진's Blog

Chain of Responsibility Pattern

Chain of Responsibility Pattern에 대해 설명하는 페이지입니다.

Posted
Preview Image
By HyunJinNo

Tags

Design Pattern, Java

1. Introduction

  • Purpose
    • Gives more than one object an opportunity to handle a request by linking receiving objects together.
  • Use When
    • Multiple objects may 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 potential outcome.

2. Characteristics

  • Each object in the chain receives the request and handles it or forwards it to the next object.
  • Object making the request has no knowledge of which object is handling the request.
  • The request has an implicit receiver.
  • Each object in the chain shares a common interface for handling requests and accessing its successor on the chain.

3. Participants

  • Handler
    • defines an interface for handling the requests
    • (optional) implements the successor link
  • Concrete Handler
    • handles requests it it responsible for
    • can access its successor
    • if the Concrete Handler can handle the request, it does so; otherwise it forwards the request to its successor
  • Client
    • initiates the request to a Concrete Handler object on the chain

4. Pros and Cons

  • Benefits
    • Decoupling of senders and receivers
    • Added flexibility
    • Sender doesn't need to know specifically who the handlers are
  • Potential Drawbacks
    • Client can't explicitly specify who handles a request
    • No guarantee of request being handled (request falls off end of chain)

5. How to Use (Example)

  • Handler

    java
    1public abstract class Handler {
    2    protected Handler successor;
    3
    4    public void setSuccessor(Handler successor) {
    5        this.successor = successor;
    6    }
    7
    8    public abstract void handleRequest(int request);  // your request to be handled
    9}
  • Concrete Handler

    java
    1public class ConcreteHandler1 extends Handler {
    2    @Override
    3    public void handleRequest(int request) {
    4        if (request >= 0 && request < 10) {
    5            System.out.println("ConcreteHandler1 handled request " + request);
    6        } else if (successor != null) {
    7            successor.handleRequest(request);
    8        }
    9    }
    10}
    java
    1public class ConcreteHandler2 extends Handler {
    2    @Override
    3    public void handleRequest(int request) {
    4        if (request >= 10 && request < 20) {
    5            System.out.println("ConcreteHandler2 handled request " + request);
    6        } else if (successor != null) {
    7            successor.handleRequest(request);
    8        }
    9    }
    10}
  • Client

    java
    1public class Main {
    2    public static void main(String[] args) {
    3        Handler h1 = new ConcreteHandler1();
    4        Handler h2 = new ConcreteHandler2();
    5        h1.setSuccessor(h1);
    6
    7        int[] requests = new int[] { 5, 7, 13, 19, 20 };
    8
    9        for (int request : requests) {
    10            h1.handleRequest(request);
    11        }
    12    }
    13}

© HyunJinNo. Some rights reserved.