Chain of Responsibility Pattern creates a chain of receiver objects for a request, decoupling the sender and receiver of the request. This design pattern falls under the category of behavioral patterns. In this pattern, each receiver usually contains a reference to another receiver. If an object cannot handle the request, it passes the same request to the next receiver, and so on.
In object-oriented design, the Chain of Responsibility Pattern is composed of a command object source and a series of handling objects. Each handling object contains logic that defines the type of command objects it can handle, and the remaining objects are passed to the next handling object in the chain. To avoid coupling the request sender and receiver together and allow multiple objects to potentially receive the request, these objects are connected in a chain, and the request is passed along the chain until an object handles it. The handlers on the chain are responsible for processing the request, and the client only needs to send the request to the chain, without worrying about the details of request handling and propagation. Therefore, the Chain of Responsibility decouples the sender and receiver of the request.
It reduces coupling by decoupling the sender and receiver of the request.
It simplifies objects by eliminating the need for objects to know the structure of the chain.
It enhances flexibility in assigning responsibilities to objects, allowing dynamic addition or removal of responsibilities by changing the members within the chain or their order.
It facilitates the addition of new request handling classes.
/*
When an account is set with three payment methods: bank, paypal, and bitcoin,
with balances of 100RMB, 200RMB, and 300RMB respectively,
the payment priority is bank, then paypal, and finally bitcoin.
When trying to purchase something worth 251RMB using the Chain of Responsibility pattern,
first, the bank account is checked for purchase eligibility. If eligible, the purchase is made and the chain is broken.
If not, the request will move on to the paypal account to check if the amount is sufficient.
If it is, the purchase will be made and the chain will be broken.
Otherwise, the request will continue to be forwarded until a suitable handler is found.
Here, bank, paypal, and bitcoin serve as links in the chain,
and the entire phenomenon is the responsibility chain.
*/classAccount{setNext(mode){this.mode = mode;}pay(amountToPay){if(this.canPay(amountToPay)){ console.log(`Paid ${amountToPay} using ${this.name}`);}elseif(this.mode){ console.log(`Cannot pay using ${this.name}. Proceeding...`);this.mode.pay(amountToPay);}else{ console.log("None of the accounts have enough balance");}}canPay(amount){returnthis.balance >= amount;}}classBankextendsAccount{constructor(balance){super();this.name ="bank";this.balance = balance;}}classPaypalextendsAccount{constructor(balance){super();this.name ="Paypal";this.balance = balance;}}classBitcoinextendsAccount{constructor(balance){super();this.name ="bitcoin";this.balance = balance;}}(function(){const bank =newBank(100);// Bank with balance 100const paypal =newPaypal(200);// Paypal with balance 200const bitcoin =newBitcoin(300);// Bitcoin with balance 300 bank.setNext(paypal); paypal.setNext(bitcoin);
bank.pay(251);// Cannot pay using bank. Proceeding...// Cannot pay using Paypal. Proceeding...// Paid 251 using bitcoin