Browse Java Design Patterns & Enterprise Application Architecture

Implementing Decorator Pattern in Java

Implement Java decorators by wrapping a small interface, delegating cleanly, and keeping each added behavior narrow and explicit.

Decorator: A wrapper that adds behavior to an object while keeping the same client-facing contract.

Decorator is strongest in Java when behavior is optional, order-sensitive, and easier to express as wrapping than as subclass inheritance.

Start With A Narrow Component Interface

1public interface ReportRenderer {
2    String render(Report report);
3}

A concrete component provides the base behavior:

1public final class BaseReportRenderer implements ReportRenderer {
2    @Override
3    public String render(Report report) {
4        return report.body();
5    }
6}

Wrap, Delegate, Extend

 1public abstract class ReportRendererDecorator implements ReportRenderer {
 2    protected final ReportRenderer delegate;
 3
 4    protected ReportRendererDecorator(ReportRenderer delegate) {
 5        this.delegate = delegate;
 6    }
 7}
 8
 9public final class AuditingRenderer extends ReportRendererDecorator {
10    public AuditingRenderer(ReportRenderer delegate) {
11        super(delegate);
12    }
13
14    @Override
15    public String render(Report report) {
16        System.out.println("Rendering report " + report.id());
17        return delegate.render(report);
18    }
19}

The key rule is simple: the decorator should preserve the contract and add one clear piece of behavior around delegation.

Good Java Fit

Decorator is a strong fit for:

  • stream and I/O style wrappers
  • logging, tracing, metrics, and auditing
  • authorization or validation around a service boundary
  • output formatting or post-processing

Bad Java Fit

Decorator becomes a problem when:

  • decorators depend on undocumented ordering
  • each decorator mutates hidden shared state
  • the wrapped interface is so large that every decorator becomes boilerplate-heavy

If that happens, the design probably wants a pipeline, interceptor chain, or explicit orchestration object instead.

Loading quiz…
Revised on Thursday, April 23, 2026