Skip to main content

Decorator Pattern

Pronunciation
DEK-uh-ray-ter PAT-urn
Updated 2 min read

Share this page

Send the link, quote the definition with a link back, or show it as a card on your own site.

https://softwaredictionary.org/terms/decorator-pattern

In short

The decorator pattern adds behavior like logging or caching to an object by wrapping it in another with the same interface, without changing the original.

What is the decorator pattern?

Suppose you have a DataSource that reads and writes files, and you want compression and encryption as options. Subclasses for every combination quickly multiply. With decorators, EncryptedSource and CompressedSource each wrap any DataSource, do their extra work and pass calls through to the object inside. You can stack them in any order: new EncryptedSource(new CompressedSource(new FileSource(path))).

It is one of the original design patterns described in the Gang of Four book in 1994. Because each decorator has the same interface as the object it wraps, callers can't tell the difference, which follows the open/closed principle: behavior is extended by adding new classes, not by editing existing ones. Java's I/O streams, such as BufferedInputStream around FileInputStream, are a classic example.

The same idea appears in many forms. Web middleware wraps a request handler with logging, authentication and error handling; HTTP clients wrap transports with retries and caching; and higher-order functions wrap a function to add timing or memoization. Python's @decorator syntax and TypeScript decorators are language features built on this wrapping idea, although they decorate functions and classes rather than individual objects.

A common misconception is that decorators are free. Many layers of wrapping make stack traces long and behavior harder to follow, and the order matters: caching before or after authentication gives very different results. Keep each decorator small and focused, and make the order of wrapping explicit in one place.

Key takeaways

  • A decorator wraps an object with the same interface and adds behavior.
  • Decorators can be stacked in any combination and order.
  • It extends behavior without editing existing classes.
  • Middleware, stream wrappers and higher-order functions use the idea.
  • Wrapping order matters, and deep stacks are harder to debug.

Example

Stacking decorators around a service (TypeScript)typescript
interface PriceService {
  getPrice(productId: string): Promise<number>;
}

class ApiPriceService implements PriceService {
  async getPrice(id: string) { return fetchPriceFromApi(id); }
}

class CachedPrices implements PriceService {
  private cache = new Map<string, number>();
  constructor(private inner: PriceService) {}
  async getPrice(id: string) {
    if (!this.cache.has(id)) this.cache.set(id, await this.inner.getPrice(id));
    return this.cache.get(id)!;
  }
}

class LoggedPrices implements PriceService {
  constructor(private inner: PriceService) {}
  async getPrice(id: string) {
    console.time(id);
    try { return await this.inner.getPrice(id); } finally { console.timeEnd(id); }
  }
}

// Same interface, extra behavior layered on
const prices: PriceService = new LoggedPrices(new CachedPrices(new ApiPriceService()));

Readers ask

What is the difference between the decorator pattern and inheritance?

Inheritance adds behavior at compile time by creating subclasses, and combinations need a class each. Decorators add behavior at runtime by wrapping objects, so features can be combined freely without a class for every combination.

Are Python decorators the decorator pattern?

They are related but not identical. Python's @ syntax wraps functions or classes with another function, a language feature inspired by the same idea. The design pattern wraps objects that share an interface.

What is the difference between a decorator and an adapter?

A decorator keeps the same interface and adds behavior. An adapter changes the interface so that an object can be used where a different one is expected.

See also

Spotted a mistake or something missing on this page?Suggest an edit

Read a random page
Open today's review
Switch to the dark theme
Read this page in Türkçe

More

Settings