Chain of Responsability

About

This pattern helps in creating failovers for Objects, so that if one of them fails another one will try to execute the logic.

Like a chain at each failure to execute, next object is called, retrying the execution.

circle-info

It is possible to implement a retry on the service failed, before calling next.

Example

Lets suppose we have services to process payments, like PjBankGateway and CieloBankGateway which is a gateway for an external service.

So we will try to process the payment with one of them, and if for some reason it fails it will automatically try to run the payment process with the other.

PaymentProcessor.ts
export default interface PaymentProcessor {
    next?: PaymentProcessor;
    processPayment(input: Input): Promise<Output>;
}

export class PjBankProcessor implements PaymentProcessor {
    constructor(readonly next?: PaymentProcessor) {}
    
    async processPayment(input: Input): Promise<Output> {
        try {
            const pjBankGateway = new PjBankGateway();
            return await pjBankGateway.createTransaction(input);
        } catch(error: any) {
            if (!this.next) throw new Error('Out of processors.');
            return this.next.processPayment(input);
        }
    }
}

export class CieloBankProcessor implements PaymentProcessor {    
    constructor(readonly next?: PaymentProcessor) {}
    
    async processPayment(input: Input): Promise<Output> {
        try {
            const cieloBankGateway = new CieloBankGateway();
            return await cieloBankGateway.createTransaction(input);
        } catch(error: any) {
            if (!this.next) throw new Error('Out of processors.');
            return this.next.processPayment(input);
        }
    }
}
circle-exclamation

Last updated