Patrones de diseño: Chain of Responsability

La definición de Chain of Responsability

¿Cómo sabemos cuando usarlo?

  • ¿El cliente del pedido ya tiene pedidos previos?
  • ¿El cliente del pedido realiza el pago con método de pago habitual?
  • ¿El pedido es superior a cierta cantidad?

¿Cómo lo implementamos?

Ventajas del uso del patrón

  • Manejas el orden de los pasos: Controla el orden en el que se ejecutan los pasos de manera dinámica
  • Aplicas el principio Single Responsibility Principle: Desacopla en clases la invocación de las operaciones y la realización de la propia acción. Pudiendo testear fácilmente cada acción por separado
  • Aplicas el principio Open/Closed Principle: Permite ampliar con nuevos manejadores sin romper código existente, mejorando así la mantenibilidad.

Caso de uso real

Implementación

class AbstractFilterHandler {
constructor() {}
applyFilter() {
this._WARNING("applyFilter(elements, filters)");
}
canIHandle() {
this._WARNING("canIHandle(elements, filters)");
}
_WARNING(fName = "unknown method") {
console.warn('WARNING! Function "' + fName + '" is not overridden in ' + this.constructor.name);
}
}
export default AbstractFilterHandler;
import AbstractFilterHandler from "./filter";class ModelsFilterHandler extends AbstractFilterHandler {
applyFilter(elements, filters) {
return elements.filter(a => filters.models.includes(a.model.slug));
}
canIHandle(filters) {
return filters.models && filters.models.length > 0;
}
}
export default ModelsFilterHandler;
import * as Handlers from "./filters";

class FilterChain {
constructor(elements, filters) {
this.elements = elements;
this.filters = filters;
this.handlers = [];
}

/**
*
* @param {AbstractFilterHandler} filter
*/
addHandler(handler) {
this.handlers.push(handler);
}

applyFilters() {
let elements = this.elements;
this.handlers.forEach(handler => {
if (handler.canIHandle(this.filters)) {
elements = handler.applyFilter(elements, this.filters);
}
});

return elements;
}
}
export default FilterChain;
let chain = new FilterChain(elements, filters);
chain.addHandler(new Handlers.ModelsFilterHandler());
chain.addHandler(new Handlers.OrderByPriceFilterHandler());
let result = handler.applyFilters(elements, filters);

--

--

Full Stack Web Developer — adrianalonso.es

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store