All PatternsStructural
Decorator
Attaches additional responsibilities to objects dynamically.
HTTP middlewareStream wrappersLogging decorators
Understanding Decorator
The Decorator pattern wraps an object with additional behavior without modifying its original code. Each decorator implements the same interface as the object it wraps, so decorators can be stacked — adding logging, then authentication, then caching — all transparently. In Go, this pattern is the foundation of http.Handler middleware chains, where each middleware wraps the next handler, adding cross-cutting concerns like CORS, rate limiting, or request tracing.
Key Concepts
- •Same interface — both the base component and decorators implement the same interface, making them interchangeable
- •Wrapping composition — each decorator holds a reference to the next component in the chain and delegates to it
- •Stackable — decorators can be combined in any order and quantity, with behavior flowing through the entire chain
- •Open/Closed principle — extend behavior by adding new decorators, without modifying existing component code
When to Use
✅ Use when
- • Adding behavior to individual objects without affecting others
- • Building middleware pipelines (HTTP, gRPC, message processing)
- • You need to combine behaviors in different ways at runtime
- • Subclassing would result in an explosion of classes for each combination
⚠️ Avoid when
- • The order of decorators matters and is hard to get right
- • Deeply nested decorators become hard to debug and trace
- • A simple function composition would be clearer in Go
Structure
<<Component Interface>>
↓ implements
Base
Decorator A
wraps ↓
Decorator B
wraps ↓
Base
How It Works
BaseHandler
Handle()
1
Base Component
Start with a base component that has core functionality.
1 / 4
Basic Implementation
Coffee shop with customizable add-ons:
main.go
Loading editor...
Real-World Example: HTTP Middleware
Request handling with authentication and logging decorators:
main.go
Loading editor...