Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Gof Decorator

ASecurity

Decorator in modern Java: wrapping an object in something of its own interface to add behaviour, stackably, at runtime — and the fact that the stacking order changes the semantics. Covers the ordering of retry, timeout, circuit breaker, cache, metrics and logging and what each arrangement means, retry amplification across layers, the identity loss that breaks ==, instanceof and listener deregistration, when a framework interceptor is the same pattern already provided, and the thread-safety a ...

2 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmentgojavasqlspringtestingperformance

Works with

cli

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add robsonkades/agent-skills --skill gof-decorator --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gof Decorator?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Gof Decorator
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/robsonkades-gof-decorator/badge)](https://www.skillsdirectory.com/skills/robsonkades-gof-decorator)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: gof-decorator
description: >
  Decorator in modern Java: wrapping an object in something of its own interface to add
  behaviour, stackably, at runtime — and the fact that the stacking order changes the semantics.
  Covers the ordering of retry, timeout, circuit breaker, cache, metrics and logging and what
  each arrangement means, retry amplification across layers, the identity loss that breaks ==,
  instanceof and listener deregistration, when a framework interceptor is the same pattern
  already provided, and the thread-safety a stateful decorator introduces. Use when resilience
  or observability layers are added around a client, when a wrapper chain is reordered, when a
  decorated object fails an instanceof check, when retries appear at two levels, or when a
  wrapper is proposed that changes the interface. Does not cover changing an interface
  (gof-adapter), controlling access to an object (gof-proxy), one entry point over a subsystem
  (gof-facade), or the individual protection policies (circuit-breakers,
  retries-and-backoff, timeouts-and-deadlines).
---

# Decorator

## Purpose

Add behaviour to one object without changing its type, and let several such additions compose.
The defining property is that the wrapper implements the same interface as what it wraps — which
is what makes the layers stackable, and what makes their order meaningful.

Order is not a detail. Retry outside timeout and timeout outside retry are both reasonable
designs with different semantics, and a stack assembled without deciding which one is intended
will behave in whichever way the wiring happened to produce.

Start with the caller's contract and the effective client/framework configuration: ordinary
success, failure, cache hit and cancellation may traverse different layers. Preserve accepted
return values, nullability, failure classification, ownership and mandatory checks across that
composition; implementing the same interface alone does not establish substitutability. Inspect
existing tests and policies before asking about material gaps such as replay safety or cache
eligibility. Keep an adequate existing client or simpler composed class when no added layer is needed.

## When it is the answer

```text
Behaviour must be added to some instances and not others, chosen at
wiring time
        → Decorator. Inheritance would decide it at compile time.

Several independent additions must combine, and combinations
multiply (retry × cache × metrics × tracing)
        → Decorator. Subclasses would be the product; wrappers are the sum.

The addition is cross-cutting and the interface is stable
        → Decorator — or the framework's own mechanism, which is the
          same pattern already implemented (see below).
```

## When it is not

- **The wrapper changes the interface.** That is an Adapter (`gof-adapter`).
- **The primary intent is substituting for another object while controlling access** — lazy
  loading, remoting or access checks. That is usually Proxy. Both patterns commonly implement the
  same interface and may be structurally identical, so classify by responsibility (`gof-proxy`).
- **Only one stable combination is ever used.** A composed class may make the call graph easier to
  inspect, but separate decorators can remain worthwhile for independent ownership, testing or
  framework integration. Compare change coupling rather than counting combinations.
- **The framework already provides it.** Servlet filters, `HandlerInterceptor`, Spring AOP
  advice, `RestClient` request interceptors, Micrometer instrumentation and Resilience4j
  decorators already provide composition mechanisms. Verify their ordering, async-context and
  observability semantics; hand-rolling beside them otherwise puts policy in two places.
- **Behaviour differs by the object's state.** That is State (`gof-state`).

## Ordering is semantics

Examples are partial Java 17 unless a framework is named. Inspect the project's resolved framework,
HTTP provider and instrumentation versions; no decorator choice authorizes upgrades or dependencies.

```text
Read a stack outermost-first. Each layer sees the one below it as
"the call".

  Metrics(          ← counts logical operations, one per caller request
    CircuitBreaker(  ← opens on the outcome of whole operations
      Retry(          ← its attempts are invisible to the breaker above
        Timeout(       ← bounds ONE attempt
          Client)))))

  Metrics(
    Retry(
      CircuitBreaker(  ← sees each attempt; reject open-breaker failures from retry eligibility
        Timeout(
          Client))))
```

| Arrangement                    | Meaning                                                 | Choose when                                      |
| ------------------------------ | ------------------------------------------------------- | ------------------------------------------------ |
| Timeout **inside** Retry       | Per-attempt bound plus backoff/queueing in total        | Pair with remaining caller budget                |
| Timeout **outside** Retry      | Outer completion bound; inner work must honor deadline  | Propagate cancellation and remaining time        |
| Cache **outside** Retry        | A valid hit avoids downstream retries                   | Hit semantics and cache failure policy permit it |
| Cache **inside** Retry         | Each attempt consults cache; concurrent fill may matter | Explicit cache/load/concurrency contract         |
| Breaker **outside** Retry      | The breaker sees logical operations                     | Operation-level failure isolation is intended    |
| Breaker **inside** Retry       | Breaker counts attempts; rejection must not be retried  | Attempt-level failure isolation is intended      |
| Metrics **outside** everything | Latency includes work below this measurement boundary   | Usually retain as logical-operation telemetry    |
| Metrics **inside** Retry       | Per-attempt counts and error rates                      | In addition, under a different metric name       |

A common starting point is **logical metrics → propagated deadline/budget → breaker → retry →
per-attempt timeout → client**, with separate attempt telemetry. It is not universal: breaker
placement decides whether it counts attempts or logical failures, and the retry must derive each
attempt budget from remaining time. Document and test the selected semantics because the type
system does not record them.

## Decision rules

```text
IF retries exist at more than one layer of the system
THEN attempts can multiply: 3 at the client × 3 at the gateway = 9 requests
     to a struggling dependency. Prefer one owner per failure domain; multiple layers
     require a shared attempt/deadline budget and evidence that they do not amplify
     (retries-and-backoff, cascading-failures).

IF a retry decorator wraps a non-idempotent operation
THEN it can duplicate side effects. Require provider-enforced idempotency within its scope,
     matching parameters/retention, or an independently safe operation; a key alone proves nothing
     (idempotency).

IF callers use ==, instanceof or equals on the decorated object
THEN inspect the actual identity/equality contract. Interface instanceof still works; concrete
     checks may fail. Preserve registration identity; avoid automatic equality forwarding or an
     unrestricted unwrap path that bypasses access, transaction or lifecycle policy.

IF the decorator holds state — a cache, a counter, a breaker
THEN determine whether it is shared or confined. Shared composition must protect each layer's
     invariants and relevant aliases; a thread-safe delegate does not protect wrapper state.

IF the framework has a mechanism for this concern
THEN prefer it when it satisfies the contract; verify ordering, metrics and tracing configuration.
     Custom composition remains valid when integrated explicitly or the framework cannot fit.

IF the stack obscures call order, context propagation or failure attribution
THEN make wiring observable, collapse inseparable policies, or use a framework chain.
     Depth alone is not the decision criterion.

IF a decorator swallows or translates the delegate's exceptions
THEN compare the resulting outcome with the caller's documented contract. Permitted translation
     can remain decoration; silent success or reclassification can hide failure or cause unsafe retry.
```

## Cross-cutting checks

- **Concurrency.** A decorator over a stateless, thread-safe delegate can make the composition
  unsafe: a counter, a cache, an `HashMap` of in-flight keys, a non-atomic read-modify-write of a
  breaker's state. Each stateful layer needs its own memory-model argument. Conversely,
  safety can also come from confinement or separate owned instances; synchronization must cover
  all conflicting access, including aliases outside the wrapper (`java-memory-model`).
- **Distribution.** This is where resilience layers live, so the ordering table above is a
  production concern rather than a stylistic one. Two failures dominate: retry amplification
  across layers, which converts a partial outage into a full one; and a timeout placed so that
  the total call time exceeds the caller's deadline, so the caller gives up while the work
  continues (`timeouts-and-deadlines`, `cascading-failures`).
- **Lifecycle.** Specify owned versus borrowed delegates and who closes returned resources or
  completes asynchronous work. Closing the wrapper, returning from a call or completing a caller
  future must not prematurely close shared resources or release a still-used permit. Inspect all
  entry points, including default/bulk methods and `close`/`flush`, for bypass or double application
  (`java-resource-management`, `cancellation-and-interruption`).
- **Performance.** Each layer adds a dispatch opportunity that HotSpot may inline at stable call
  sites. Costs that often matter more are allocation per call inside a
  layer (a new context object, a lambda capturing state, a `String` built for a log line that is
  then discarded), and lost inlining once the call site is megamorphic
  (`jit-inlining-and-escape-analysis`).
- **Testing.** Test each decorator against a fake delegate — that is the pattern's dividend. Then
  write a composed-stack test with discriminating observations: attempt versus logical counts,
  zero downstream calls on an eligible cache hit, and no new attempt after the budget expires.
  Include failure paths; best-effort telemetry must not replace a business result or mask its
  failure. Mandatory audit behavior needs its own explicit contract.

## Review checklist

- [ ] The wrapper implements the same interface and preserves the accepted caller contract
- [ ] The stacking order is deliberate and documented at the wiring site
- [ ] Retry ownership and the shared attempt/deadline budget prevent cross-layer amplification
- [ ] Retry safety is established by the operation/provider contract, not merely the presence of a key
- [ ] Caller wait and remaining-work enforcement are verified separately against the deadline
- [ ] Stateful layers state their thread-safety guarantee
- [ ] Delegate, returned-result and permit ownership cover initialization, close and async failure
- [ ] Identity-sensitive behavior is eliminated, explicitly delegated, or exposed through a
      constrained standard unwrap contract rather than concrete-type assumptions
- [ ] No decorator silently swallows or reclassifies the delegate's failures
- [ ] A test asserts the composed order, not only each layer alone

Finish with the retained or revised stack, its observation/ownership boundaries, material unresolved
policies and actual validation. Separate proposed tests from executed checks; a review need not add wrappers.

## References

- [Ordering and composition](references/ordering-and-composition.md) — every common layer pair
  with its semantics, retry amplification arithmetic, deadline propagation through a stack,
  identity loss and unwrapping (`java.sql.Wrapper`, AOP proxies, listener deregistration), and
  when a framework interceptor should replace a hand-rolled decorator. Read before assembling or
  reordering a stack.
- [Worked example](references/worked-example.md) — an outbound pricing client decorated for
  metrics, breaking, retry, timeout and caching: the wiring with its order justified, the
  per-layer tests, the order test, and an illustrative amplification scenario. Read when
  implementing.

Attribution

robsonkadesrobsonkades
View sourceMore from robsonkades →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →