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:
Example | Source Code Link |
---|---|
Example #1: Caching Data | GitHub |
Other Code Implementations
Use the following links to check the Chain of Responsibility pattern implementation in other programming languages.