Skip to content

Latest commit

 

History

History
129 lines (108 loc) · 2.84 KB

File metadata and controls

129 lines (108 loc) · 2.84 KB

JavaScript Example

/**
 * The default chaining behavior can be implemented inside a base handler class.
 */
class HandlerAbstract {
  #nextHandler;

  setNext(handler) {
    this.#nextHandler = handler;
    // Returning a handler from here will let us link handlers in a
    // convenient way like this:
    // monkey.setNext(squirrel).setNext(dog);
    return handler;
  }

  handle(request) {
    if (this.#nextHandler) {
      return this.#nextHandler.handle(request);
    }
    return null;
  }
}

module.exports = HandlerAbstract;
const HandlerAbstract = require("./HandlerAbstract");

/**
 * All Concrete Handlers either handle a request or pass it to the next handler
 * in the chain.
 */
class DogHandler extends HandlerAbstract {
  handle(request) {
    if (request === "MeatBall") {
      return `Dog: I'll eat the ${request}.`;
    }
    return super.handle(request);
  }
}

module.exports = DogHandler;
const HandlerAbstract = require("./HandlerAbstract");

/**
 * All Concrete Handlers either handle a request or pass it to the next handler
 * in the chain.
 */
class MonkeyHandler extends HandlerAbstract {
  handle(request) {
    if (request === "Banana") {
      return `Monkey: I'll eat the ${request}.`;
    }
    return super.handle(request);
  }
}

module.exports = MonkeyHandler;
const HandlerAbstract = require("./HandlerAbstract");

/**
 * All Concrete Handlers either handle a request or pass it to the next handler
 * in the chain.
 */
class SquirrelHandler extends HandlerAbstract {
  handle(request) {
    if (request === "Nut") {
      return `Squirrel: I'll eat the ${request}.`;
    }
    return super.handle(request);
  }
}

module.exports = SquirrelHandler;
const DogHandler = require("./DogHandler");
const MonkeyHandler = require("./MonkeyHandler");
const SquirrelHandler = require("./SquirrelHandler");

/**
 * The client code is usually suited to work with a single handler. In most
 * cases, it is not even aware that the handler is part of a chain.
 */
function clientCode(handler) {
  const foods = ["Nut", "Banana", "Cup of coffee"];

  for (const food of foods) {
    console.log(`Client: Who wants a ${food}?`);

    const result = handler.handle(food);
    if (result) {
      console.log(`  ${result}`);
    } else {
      console.log(`  ${food} was left untouched.`);
    }
  }
}

/**
 * The other part of the client code constructs the actual chain.
 */
const monkey = new MonkeyHandler();
const squirrel = new SquirrelHandler();
const dog = new DogHandler();

monkey.setNext(squirrel).setNext(dog);

/**
 * The client should be able to send a request to any handler, not just the
 * first one in the chain.
 */
console.log("Chain: Monkey > Squirrel > Dog\n");
clientCode(monkey);
console.log("");

console.log("Subchain: Squirrel > Dog\n");
clientCode(squirrel);