Design Pattern: Chain of Responsibility Pattern in Java

Chain of Responsibility pattern is used to decouple the request and response handling. Multiple objects create a chain that is used to handle a request.

This article demonstrates Chain of Responsibility pattern implementations in Java. Check the following examples.

Examples

Check the following examples of Chain of Responsibility pattern in Java-

Example #1: Caching Data

Let’s take the example of caching data. We want to cache “CSS” or “JavaScript” in some CDN. If data is not “CSS” or “JavaScript” then we want to store it in either Redis(for data less than 1024 characters) or in Disk.

General Class for Data [not related to the pattern implementation]

// Data.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

enum DATA_TYPE {
    DATA,
    JAVASCRIPT,
    CSS
};

public class Data {
    private final DATA_TYPE type;
    private final String data;
    private final String key;

    public Data(DATA_TYPE type, String key, String data) {
        this.type = type;
        this.key = key;
        this.data = data;
    }

    public DATA_TYPE getType() {
        return type;
    }

    public String getKey() {
        return key;
    }

    public String getData() {
        return data;
    }
}

Cache Handler [abstract class]

// CacheHandler.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

public abstract class CacheHandler {
    public CacheHandler nextCacheHandler;

    public CacheHandler(CacheHandler nextCacheHandler) {
        this.nextCacheHandler = nextCacheHandler;
    }

    public abstract void handleRequest(Data data);
}

Concrete Handler Classe for CDN

In the handleRequest method check if the data type is “CSS” or “JAVASCRIPT” and if yes then save that in CDN, else send the request to the next handler.

// CdnCacheHandler.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

public class CdnCacheHandler extends CacheHandler {
    public CdnCacheHandler(CacheHandler nextCacheHandler) {
        super(nextCacheHandler);
    }

    @Override
    public void handleRequest(Data data) {
        if (data.getType() == DATA_TYPE.CSS || data.getType() == DATA_TYPE.JAVASCRIPT) {
            // Write code to send the data file to some CDN

            System.out.println("Caching file '" + data.getKey() + "' in CDN");
        } else if (nextCacheHandler != null) {
            nextCacheHandler.handleRequest(data);
        }
    }
}

Concrete Handler Class for Redis

In the handleRequest method check if the data length is less than or equal to 1024. If true then save that in Redis, else send the request to the next handler.

// RedisCacheHandler.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

public class RedisCacheHandler extends CacheHandler {
    public RedisCacheHandler(CacheHandler nextCacheHandler) {
        super(nextCacheHandler);
    }

    @Override
    public void handleRequest(Data data) {
        if (data.getType() == DATA_TYPE.DATA && data.getData().length() <= 1024) {
            // Write code to cache data in Redis

            System.out.println("Caching data '" + data.getKey() + "' in Redis");
        } else if (nextCacheHandler != null) {
            nextCacheHandler.handleRequest(data);
        }
    }
}

Concrete Handler Classe for Disk

In the handleRequest method check if the data length is greater than 1024. If true then save that in Disk, else send the request to the next handler.

// DiskCacheHandler.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

public class DiskCacheHandler extends CacheHandler {
    public DiskCacheHandler(CacheHandler nextCacheHandler) {
        super(nextCacheHandler);
    }

    @Override
    public void handleRequest(Data data) {
        if (data.getType() == DATA_TYPE.DATA && data.getData().length() > 1024) {
            // Write code to cache data in Disk

            System.out.println("Caching data '" + data.getKey() + "' in Disk");
        } else if (nextCacheHandler != null) {
            nextCacheHandler.handleRequest(data);
        }
    }
}

Demo

While using it, chain the handlers, so that any handler can pick the request and process it.

// Demo.java

package com.bigboxcode.designpattern.chainofresponsibility.cache;

public class Demo {

    public static void main(String[] args) {
        DiskCacheHandler cacheHandler = new DiskCacheHandler(new RedisCacheHandler(new CdnCacheHandler(null)));

        Data data = new Data(DATA_TYPE.DATA, "key1", "ABC320489un3429rn29urn29r82n9jfdn2");

        cacheHandler.handleRequest(data);

        data = new Data(DATA_TYPE.CSS, "key2", ".some-class{border: 1px solid red; margin: 10px}");

        cacheHandler.handleRequest(data);
    }
}

Output

Caching data 'key1' in Redis

Caching file 'key2' in CDN

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check the Chain of Responsibility pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.