Summary
Pattern Name | Chain of Responsibility Pattern |
Pattern Type | Behavioral Pattern |
Scope | Object |
Tagline | Chain the steps of processing a command |
Use cases | 1. Chain the steps of processing one after another and ensure choosing the steps on the fly during processing 2. When we want to decouple the sender and receiver of an operation |
Related Patterns | Composite |
Difficulty Level | difficult |
Implementations | ![]() ![]() ![]() ![]() |
Definition
Chain of Responsibility pattern forms a chain of objects that is responsible for handling a command/operation request. As the responsibility is distributed into one or more objects and a single object is not responsible for handling a request, so that ensures the decoupling of the request sender and processor.
The request is sent to the chain of objects without specifying the handler. Which object will handle the request is not predefined, that is decided on-the-fly while processing.
Implementation
Chain of Responsibility pattern has 2 elements involved in the implementation.
- Handler Interface: an interface(or abstract class) to ensure the common handler for the request. This defines a function for handling and might define a process for handling the next step.
- Concrete Handler Classes: classes that implement the handler interface and are responsible for handling the request.

Examples
Example #1: Caching Data
Let’s take the example of caching data.
If the file is of type “CSS” or “JavaScript” we want to cache that in some CDN.
Or if the data is normal data then we want to cached it locally. We want to cache data less than 1024 characters in Redis and larger data in the disk.
General Class for Data [not related to the pattern implementation]
enum DATA_TYPE {
DATA,
JAVASCRIPT,
CSS
}
class Data
var type: DATA_TYPE
var data: String
var key: String
constructor(typeParam: DATA_TYPE, keyParam: String, dataParam: String)
type = typeParam
key = keyParam
data = dataParam
end constructor
function getType(): DATA_TYPE
return type
end function
function getKey(): String
return key
end fuction
function getData(): String
return data
end function
end class
Cache Handler and Concrete Handler Classes
// CacheHandler abstract class
abstract class CacheHandler
var nextCacheHandler: CacheHandler
constructor(nextCacheHandlerParam: CacheHandler)
nextCacheHandler = nextCacheHandlerParam
end constructor
public abstract void handleRequest(Data data)
end class
// CdnCacheHandler
class CdnCacheHandler extends CacheHandler
constructor(nextCacheHandlerParam: CacheHandler)
super(nextCacheHandlerParam)
end constructor
function handleRequest(Data data)
if (data.getType() == DATA_TYPE.CSS || data.getType() == DATA_TYPE.JAVASCRIPT) {
// Write code to send the data file to some CDN
print("Caching file '" + data.getKey() + "' in CDN")
} else if (nextCacheHandler != null) {
nextCacheHandler.handleRequest(data)
}
end function
end class
// RedisCacheHandler
class RedisCacheHandler extends CacheHandler
constructor(nextCacheHandlerParam: CacheHandler)
super(nextCacheHandlerParam)
end constructor
function handleRequest(Data data)
if (data.getType() == DATA_TYPE.DATA && data.getData().length() <= 1024) {
// Write code to cache data in Redis
print("Caching data '" + data.getKey() + "' in Redis")
} else if (nextCacheHandler != null) {
nextCacheHandler.handleRequest(data)
}
end function
end class
// DiskCacheHandler
class DiskCacheHandler extends CacheHandler
constructor(nextCacheHandlerParam: CacheHandler)
super(nextCacheHandlerParam)
end constructor
function handleRequest(Data data) {
if (data.getType() == DATA_TYPE.DATA && data.getData().length() > 1024) {
// Write code to cache data in Disk
print("Caching data '" + data.getKey() + "' in Disk")
} else if (nextCacheHandler != null) {
nextCacheHandler.handleRequest(data)
}
end function
end class
Demo
var cacheHandler: DiskCacheHandler = new DiskCacheHandler(new RedisCacheHandler(new CdnCacheHandler(null)))
// First request
var data: Data = new Data(DATA_TYPE.DATA, "key1", "ABC320489un3429rn29urn29r82n9jfdn2")
cacheHandler.handleRequest(data)
// Second request
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
Code Implementations
Use the following links to check Singleton pattern implementation in specific programming languages.