# Chain of Responsibilty

A behavioral design pattern that lets you pass requests along a chain of handlers. Upon receiving a request, each handler decides whether to process the request or to pass it to the next handler in the chain. 

It achieves loose coupling between the sender of a request and its receiver. 

It enforces separation of concerns between the sender/ client and the handlers.

## Use Cases

This pattern is suitable when there is a need to process different kinds of requests in a various way.

You can implement this design patterns in the following use-cases.

- Filtering requests as in an authentication process.

![](https://mymakebucket1242.s3.eu-north-1.amazonaws.com/work/hashnode/9ae78b41-9e83-46d2-859c-294582e02922/image2.png)

In this case, the request will be passed to the receiver if the validation process in each handler passes.

- Finding a suitable handler as used in the customer service workflow.

![](https://mymakebucket1242.s3.eu-north-1.amazonaws.com/work/hashnode/9ae78b41-9e83-46d2-859c-294582e02922/image3.png)

In this case, the correct handler will pick up, process, and drop the request.

## Structure

![](https://mymakebucket1242.s3.eu-north-1.amazonaws.com/work/hashnode/9ae78b41-9e83-46d2-859c-294582e02922/image4.png)

## Implementation

### Classic Example

```
class Handler
{
	Handler* _nextHandler;
public:
	virtual Handler* SetNext(Handler *handler) = 0;
	virtual std::string Handle(std::string request) = 0;
};

class DefaultAbstractHandler : public Handler {
	std::string Handle(std::string request) override {
		if (_nextHandler != nullptr) {
				return _nextHandler->Handle(request);
		}
		
		return {};
	}
	
	Handler* SetNext(Handler* handler) override {
		_nextHandler = handler;
		return handler; // so you can link the next handler in a convenient way.
	}
}

class SmallHandler: public DefaultAbstractHandler {
	std::string Handle(std::string request) override {
		if (request == "small") {
			return "Small handler\n";
		} else {
			return DefaultAbstractHandler::Handle(request);
		}	
	}
}

...

int main() {
	SmallHandler* smallHandler = new SmallHandler;
	MediumHandler* mediumHandler = new mediumHandler;
	smallHandler->SetNext(mediumHandler);
	
	std::vector<std::string> requests {"small", "medium", "large"};
	for (auto& inp: requests) {
		smallHandler->Handle(inp);
	}
}
```

### Improving Classic Example using  std::vector  

Improve further decoupling → Handlers are not aware of each other anymore

```
class PriceHandler {
	std::vector<PriceReceiver*> _receivers;
	
public:
	virtual PriceHandler* SetNext(PriceReceiver* handler) {
		_receivers.push_back(handler);
		return this;
	}
	
	virtual double HandlePrice(Ticket ticket) {
		for (auto receiver: _receivers) {
			double res = ...;
			
			if (res) {
				return res;
			}
		}
		
		return 0;
	}
	
	virtual double HandleTotalPrice(std::vector<Ticket> tickets) {
		for (Ticket ticket: tickets) {
			totalPrice += HandlePrice(ticket);
		}
		
		return totalPrice;
	}
}
```

### Using Boost Event

Mentioned  [here](https://vishalchovatiya.com/posts/chain-of-responsibility-design-pattern-in-modern-cpp/) .

This implementation, however, does not allow you to drop a request if it has been handled.

## Image Credits

[Chain of Responsibility in C++ / Design Patterns (refactoring.guru)](https://refactoring.guru/design-patterns/chain-of-responsibility/cpp/example)



