Command Palette

Search for a command to run...

PHASE 2Beginner ~6 min· topic 7 of 22Structural

Structural 2 — Decorator

In one line

Wrap an object to add behavior at runtime, stackable without touching the original class.

0/22 · 0%

Think of it like this

Coffee toppings. Start with plain coffee, add milk, then caramel, then whipped cream. Each topping wraps the coffee and adds a bit to the price, and you can stack them in any order.

Key ideas

  1. 01

    Solves: adding responsibilities (logging, compression, rate-limiting, retries) without a class explosion.

  2. 02

    Stack of wrappers: BufferedInputStream → Java's classic example.

  3. 03

    Same interface on the wrapper — clients don't know they're decorated.

  4. 04

    Interview favorite: coffee/beverage pricing, or decorating a rate limiter around a cache.

Java / Spring map

  • →

    java.io (BufferedInputStream wraps FileInputStream); Spring's @Transactional proxies are decorators.

Code & diagrams

Decorator.javajava

Rate limiter wrapped around a ticket repository.

public interface TicketRepository { Ticket findBy(String id); }

public class DbTicketRepository implements TicketRepository {
  public Ticket findBy(String id) { return new Ticket(id); } /* real DB call */
}

// decorator #1: adds rate limiting without editing DbTicketRepository
public class RateLimitedTicketRepository implements TicketRepository {
  private final TicketRepository delegate;
  private final RateLimiter limiter;
  public RateLimitedTicketRepository(TicketRepository d, RateLimiter l) {
    this.delegate = d; this.limiter = l;
  }
  public Ticket findBy(String id) {
    if (!limiter.allow("read-ticket")) throw new TooManyRequests();
    return delegate.findBy(id);
  }
}

// decorator #2: adds caching. Stack them freely:
// new CachedTicketRepository(new RateLimitedTicketRepository(new DbTicketRepository(), rl), cache);

Explain without notes

01

How is this different from inheritance? What does a stack of decorators look like?

Practice

01

Add Logging + Metrics decorators to NotificationSender and stack all three.

Trade-offs

  • ↔

    Decorators blur identity (equals/hashCode, instanceof) and stack order matters: cache-then-rate-limit and rate-limit-then-cache behave differently.

Completion checklist

  • I can build a stack of decorators and explain why their order changes behaviour.

Back to phase