पाठ 20 / 25

Template Method and Chain of Responsibility

Fixed skeletons and handler pipelines.

Two ways to structure steps

Template Method defines the skeleton of an algorithm in a base class and lets subclasses override specific steps (hooks). A data import might always read, validate, transform, save, with CSV and JSON importers overriding only read. It relies on inheritance, so modern code often prefers passing the varying steps as functions or objects (composition), and UI frameworks expose the same idea as lifecycle hooks. Chain of Responsibility passes a request along a chain of handlers; each one either handles it, modifies it, or passes it on. Web framework middleware (Express, Koa, ASP.NET Core) is the everyday form: authentication, rate limiting, logging and body parsing run in order, and any handler can stop the chain by responding early. Other examples: approval chains and support ticket escalation.

A minimal middleware chain

Each handler can act, then call next() or stop.

type Ctx = { req: Request; user?: User; status?: number; body?: unknown };
type Middleware = (ctx: Ctx, next: () => Promise<void>) => Promise<void>;

function compose(middlewares: Middleware[]) {
  return (ctx: Ctx) => {
    const run = (i: number): Promise<void> =>
      i < middlewares.length ? middlewares[i](ctx, () => run(i + 1)) : Promise.resolve();
    return run(0);
  };
}

const logRequest: Middleware = async (ctx, next) => {
  const start = Date.now();
  await next();
  logger.info({ path: new URL(ctx.req.url).pathname, ms: Date.now() - start, status: ctx.status });
};

const authenticate: Middleware = async (ctx, next) => {
  ctx.user = await verifyToken(ctx.req.headers.get('authorization'));
  if (!ctx.user) { ctx.status = 401; ctx.body = { error: 'Unauthorised' }; return; } // stop the chain
  await next();
};

const getProfile: Middleware = async (ctx) => { ctx.status = 200; ctx.body = ctx.user; };

const handle = compose([logRequest, authenticate, getProfile]);

Prefer hooks over deep inheritance

If a Template Method base class grows many overridable steps, consider passing a small object of step functions instead; it is easier to test and avoids fragile base classes.

त्वरित जाँच: Web framework middleware is an everyday example of which pattern?

  • Abstract Factory
  • Chain of Responsibility
  • Flyweight
  • Prototype
Answer

Chain of Responsibility — Each middleware handles the request or passes it on.