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.

Check complete details and explanations about the Chain of Responsibility pattern in the article: Chain of Responsibility Pattern

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

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 for “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

// 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

// 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

// 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

// 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

// 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:

Leave a Comment