Design Pattern means that “we had some problem then we found the solution and gave name to this solution” and Chain of responsibility is also one of the solution so we need to find the problem that Chain of responsibility has solved and how ?
This design pattern comes under Behavioral Category (It tells that how objects are communicating with each other (objects have been created already)).
================================================================
C++ Chain Of Responsibility Design Pattern :
Standard Definition:
Chain Of Responsibility Design Pattern avoid coupling the sender of request to its receiver by giving more than one object a chance to handle the request. Chain the receiving object and pass the request along the chain until an object handles it.
Problem:
In some case, we are NOT able to handle the request by single receiver or request can be handled by multiple receiver or in other word it depends on request that comes run time.
Solution:
we are creating a chain of objects (receivers) to handle a request and each object has its successor. Each object will try to handle the request and if not able to handle then it will pass request to its successor and this behaviour will go on until request is not handled, this solution called as “chain of responsibility design pattern“.
When we will use chain of responsibility pattern:
- When multiple receivers can handle the single request (Who will handle that we will get during run time).
- When sender is NOT aware about receiver, it depends upon value and we will get to know during run time so we can handle the request by giving the chance to multiple receivers.
- When multiple receivers are required to handle the single request.
Class Diagram:
Class Diagram of real example:
Source code of real example in c++:
/* * File:chainOfRes.cpp * This file is described the Chain Of Responsibility Design Pattern with help of example * Author: Alpha Master * Date: 4 Jan 2021 */ //Header File #include<iostream> //class ATM Handler class AtmHandler { AtmHandler* m_suc; public: AtmHandler(AtmHandler* s = nullptr): m_suc(s){} ~AtmHandler(){} virtual void HandleRequest(int amt); }; void AtmHandler::HandleRequest(int amt) { if(m_suc) m_suc->HandleRequest(amt); } //50 Dollar Handler class Dollar50Handler: public AtmHandler { public: Dollar50Handler(AtmHandler* s = nullptr): AtmHandler(s){} ~Dollar50Handler(){} void HandleRequest(int amt); }; void Dollar50Handler::HandleRequest(int amt) { //Handle the request otherwise pass the request if(amt%50 == 0) { std::cout<<"Number of 50 Dollar:"<<amt/50<<std::endl; std::cout<<"Request is completed so no need to forward it"<<std::endl; } else { int numberOf50Dollar= amt/50; std::cout<<"Number of 50 Dollar:"<<numberOf50Dollar<<std::endl; amt = amt-numberOf50Dollar*50; AtmHandler::HandleRequest(amt); } } //20 Dollar Handler class Dollar20Handler: public AtmHandler { public: Dollar20Handler(AtmHandler* s = nullptr): AtmHandler(s){} ~Dollar20Handler(){} void HandleRequest(int amt); }; void Dollar20Handler::HandleRequest(int amt) { //Handle the request otherwise pass the request if(amt%20 == 0) { std::cout<<"Number of 20 Dollar:"<<amt/20<<std::endl; std::cout<<"Request is completed so no need to forward it"<<std::endl; } else { int numberOf20Dollar= amt/20; std::cout<<"Number of 20 Dollar:"<<numberOf20Dollar<<std::endl; amt = amt-numberOf20Dollar*20; AtmHandler::HandleRequest(amt); } } //10 Dollar Handler class Dollar10Handler: public AtmHandler { public: Dollar10Handler(AtmHandler* s = nullptr): AtmHandler(s){} ~Dollar10Handler(){} void HandleRequest(int amt); }; void Dollar10Handler::HandleRequest(int amt) { //Handle the request otherwise pass the request if(amt%10 == 0) { std::cout<<"Number of 10 Dollar:"<<amt/10<<std::endl; std::cout<<"Request is completed so no need to forward it"<<std::endl; } else { std::cout<<"!!!!!!!!!!!!!!!!!!!Can Not with draw this amout please enter correct amount"<<std::endl; } } int main() { std::cout<<"Chain of Responsibility"<<std::endl; Dollar10Handler* p10 = new Dollar10Handler; Dollar20Handler* p20 = new Dollar20Handler(p10); Dollar50Handler* p50 = new Dollar50Handler(p20); AtmHandler* atm = new AtmHandler(p50); std::cout<<"Please withdraw 530 Dollar"<<std::endl; atm->HandleRequest(530); std::cout<<"Please withdraw 545 Dollar"<<std::endl; atm->HandleRequest(545); delete p10; delete p20; delete p50; delete atm; return 0; }
Compilation command:
g++ chainOfRes.cpp
Output:
Chain of Responsibility
Please withdraw 530 Dollar
Number of 50 Dollar:10
Number of 20 Dollar:1
Number of 10 Dollar:1
Request is completed so no need to forward it
Please withdraw 545 Dollar
Number of 50 Dollar:10
Number of 20 Dollar:2
!!!!!!!!!!!!!!!!!!!Can Not with draw this amout please enter correct amount