What is the Decorator pattern?
Quick Answer
Decorator wraps an object in another object that implements the same interface, adding behaviour before/after delegating to the inner one — without changing the original class. Classic uses: a caching decorator, a logging decorator, a retry decorator around a service, all composable.
Decorator is about wrapping an object in another object that has the same interface, so you can add behaviour around it without touching the original class. The typical examples are a caching decorator that checks the cache and only calls the real service on a miss, or a logging decorator, or a retry decorator. And because they all implement the same interface, you can stack them — logging around caching around the real implementation. It's the composition-friendly alternative to subclassing for cross-cutting concerns, and DI containers can wire the chain up for you.
class CachingProductService : IProductServiceholds an innerIProductService, checks the cache, and calls the inner on a miss.- Stack them:
new LoggingService(new CachingService(new RealService())). - DI containers (or Scrutor for MS.DI) support registering decorators declaratively.
- Preferred over subclassing for cross-cutting concerns because you can mix and match at composition time.
- ASP.NET Core middleware and Polly resilience are decorator-style composition.