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 Strategy

ASecurity

Strategy in modern Java, separated into three things that are usually conflated: the design concept (an algorithm varies), the classical class hierarchy, and the lambda or functional interface that expresses it today. Covers when a function value is enough and when a named type earns its keep, selecting a strategy by key instead of an if-else chain, the trap of strategies that differ only in constants and may be configuration, how shared state changes concurrency obligations, and the contract...

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

Works with

api

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

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

Installs into .claude/skills of the current project.

Are you the author of Gof Strategy?

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

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

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

Download Zip
Files
SKILL.md
---
name: gof-strategy
description: >
  Strategy in modern Java, separated into three things that are usually conflated: the design
  concept (an algorithm varies), the classical class hierarchy, and the lambda or functional
  interface that expresses it today. Covers when a function value is enough and when a named type earns its
  keep, selecting a strategy by key instead of an if-else chain, the trap of strategies that
  differ only in constants and may be configuration, how shared state changes concurrency
  obligations, and the contract test implementations can share. Use when an algorithm must vary
  at runtime, when a switch over a type code keeps growing, when a class hierarchy exists whose
  members are one-line methods, or when strategy classes differ only in a rate or a threshold.
  Does not cover lifecycle-governed legal operations and transitions (gof-state), two independently varying hierarchies (gof-bridge), an
  algorithm skeleton with varying steps (gof-template-method), or choosing which object to create
  (gof-factory-method).
---

# Strategy

## Purpose

Let an operation's algorithm vary independently of the code that uses it. Strategy is the most
useful and frequently over-implemented pattern in object design. The design concept can be sound
while a class hierarchy, lambda, enum strategy, table or direct branch is the better mechanism.

Three things share the name, and separating them settles most arguments:

```text
The concept        "This algorithm varies; callers rely on a shared
                   contract." Selection may still be explicit.

The class          interface + N implementations + a selector. One
hierarchy          expression of the concept, and the heaviest.

The function       a lambda or method reference passed where the
value              algorithm is needed. Another expression of the same
                   concept, and usually the right one.
```

A `Comparator` lambda is Strategy. Say so in review — recognising the intent is what keeps the
design legible; hand-building the hierarchy is what makes it bulky.

Start with consumer calls, required inputs/results/failures, the extension model and existing
selection/configuration evidence. Reuse accepted contracts before asking about material gaps;
keep an adequate branch or function. A changing policy reference alone does not justify a new pattern.

## When it is the answer

```text
An operation has more than one algorithm and the choice is made at
runtime — by configuration, by a caller, by data
        → Strategy, in whichever mechanism fits.

A switch over a type code keeps growing, and each branch is a
self-contained calculation
        → Strategy, keyed by that code.

Callers must be able to supply their own algorithm
        → Strategy as a functional interface in your public API.
```

## When it is not

- **One algorithm exists and there is no boundary/ownership reason to abstract it.** An interface
  may be premature, while a published port, platform SPI or testable external policy can justify
  one implementation (`gof-pattern-thinking`).
- **The variants differ only in data and share identical rules.** Prefer typed configuration.
  Separate named policies can still be warranted when validation, authorization, rollout,
  compatibility or lifecycle differs.
- **The behavior governs lifecycle-dependent operations and valid transitions.** That is State
  (`gof-state`). Interchangeable policies may still be selected internally or adapt to current data/load.
- **Only part of an algorithm varies, inside a fixed sequence.** Compare Template Method with
  a fixed method taking the varying part as a function, preserving existing extension contracts
  (`gof-template-method`).
- **The branches are not self-contained.** If each `switch` arm mutates shared state and depends
  on the others, extracting them into strategies moves a tangle rather than resolving it.

## Lambda or named type?

```text
A lambda / method reference is enough when:
    one operation; captured dependencies and lifetime have clear contracts;
    selection/metadata can live in a registration rather than the implementation

A named type earns its place when:
    related operations and invariants are clearer together in one implementation
      (apply and supports(...), for example)
    key/metadata and related operations belong together for cohesion
    its injected dependencies or implementation are clearer as a class
    it must appear in stack traces, thread dumps and metrics by name
    it has its own tests and its own reason to change
```

Both are Strategy. The failure is not choosing the "wrong" one — it is building a five-class
hierarchy when three lambdas would do, or scattering anonymous lambdas that nobody can find when
the calculation misbehaves in production.

## Selection

Examples are partial Java 17 snippets with application types. Sealed classes are standard in 17;
type-pattern switch is final in 21 (earlier supported releases require preview). Inspect the target
toolchain and framework configuration; no upgrade or new dependency is implied.

```java
// what grows badly
if (code.equals("FLAT")) return flat(order);
else if (code.equals("TIERED")) return tiered(order);
else if (code.equals("WEIGHT")) return byWeight(order);
// ... and the else branch, which returns zero and nobody noticed

// keyed lookup, with the failure defined
private final Map<ShippingMethod, ShippingCost> byMethod;

ShippingCost costFor(ShippingMethod method) {
    var strategy = byMethod.get(method);
    if (strategy == null) throw new UnsupportedShippingMethod(method, byMethod.keySet());
    return strategy;
}
```

Spring can inject eligible registered beans as a list or string-keyed map; classpath presence alone
does not register every implementation. Conditions, qualifiers and scanning affect the set, so an
accidental extra bean silently joins it and a missing one silently does not. Build the map from an
explicit key the strategy or registration declares, and fail at startup if a key is duplicated or a required key is
absent.

For a closed key set, compare an enum or compatible exhaustive switch with a validated registry.
Compilation checks known variants, not null inputs, binary evolution or calculation failures.

## Decision rules

```text
IF strategies differ only in values
THEN first model typed validated configuration. Keep named strategies only when the
     values carry distinct policy ownership, compatibility or behavior contracts.

IF a strategy holds mutable state and is shared
THEN define synchronization, confinement or immutable snapshots. Stateless strategies
     are easiest to share, but stateful incremental algorithms are valid when lifetime
     and thread-safety are part of the contract.

IF selection is by a chain of if-else on a code
THEN compare an exhaustive switch for a closed set with a validated map/registry for
     open contributions. Define unknown/default semantics explicitly.

IF a strategy needs to know whether it applies
THEN compare a cohesive named implementation with a predicate/function registration;
     metadata and applicability need not be abstract methods on the public functional interface.
     Consider Chain of Responsibility if several may
     apply in order (gof-chain-of-responsibility).

IF strategies are selected from data crossing a trust boundary
THEN validate/authorize against the supported registry. Extensible sets need not be
     compile-time closed, but untrusted input must never become an arbitrary class name.

IF a calculation is hard to attribute in profiles/logs
THEN use a named method/type, explicit metric tag, or registration metadata. A whole
     class is one option, not the only diagnostic identity.

IF every strategy needs the same pre- and post-processing
THEN that is a template, and it belongs in the caller once — not
     copied into each strategy.

IF the strategy choice changes system behaviour beyond this call —
partitioning, routing, serialisation
THEN inspect persisted data, in-flight work and old/new coexistence requirements.
     Incompatible placement or format changes need migration; a compatible stateless policy
     change can use a validated configuration rollout
     (message-ordering-and-partitioning).
```

## Cross-cutting checks

- **Concurrency.** A shared strategy needs an explicit synchronization/confinement or immutable-state
  contract for itself and captured/injected collaborators. The recurring bug is a strategy
  accumulating results in a field — possibly missed by a one-call test, but leaking across calls,
  with one request's data appearing in another's (`java-memory-model`).
- **Distribution.** Several of the most consequential strategies in a distributed system are
  chosen by configuration and have system-wide effects: the partitioning strategy determines
  ordering guarantees, the serialisation strategy determines compatibility, the retry policy
  determines amplification under failure, the load-balancing strategy determines tail latency.
  Assess coexistence, rollback and retained effects before choosing a rollout or migration;
  a strategy label alone does not require data migration or a compatibility window
  (`sharding-and-partitioning`, `load-balancing-and-routing`, `retries-and-backoff`).
- **Performance.** Dispatch and inlining depend on receiver profiles, compilation tier and code
  shape rather than a fixed implementation count. Non-capturing lambdas may be cached; capturing
  lambdas can allocate and either form may inline. Inspect profiles/compilation on measured hot paths
  (`jit-inlining-and-escape-analysis`).
- **Testing.** Three levels. Test each strategy against its inputs and declared state/lifecycle;
  strategies are not inherently pure. Test the selector separately, including the
  unknown-key case. And a shared contract test that every implementation must pass, which is what
  stops the fifth strategy from quietly violating an invariant the first four honour.

## Review checklist

- [ ] Variation exists today, or a concrete port/SPI/ownership boundary justifies one implementation
- [ ] Variants justify behavior or a named policy/ownership reason; data-only alternatives were considered
- [ ] Strategy state has explicit immutability, confinement or synchronization semantics
- [ ] Selection matches the extension model; unknown/default semantics are deliberate
- [ ] External keys are validated/authorized against a supported registry
- [ ] Diagnostic identity is available through named methods/types or bounded registration metadata
- [ ] Shared pre/post processing lives in the caller, not duplicated per strategy
- [ ] A contract test runs against every implementation
- [ ] System-wide policy changes have an evidence-based rollout or migration that preserves required contracts

## References

Deliver the variation and contract, chosen mechanism/selector, state ownership and failure behavior,
plus focused checks. Keep performance benefits conditional on measurements.

- [Concept, mechanism and selection](references/concept-mechanism-selection.md) — the three levels
  in detail; lambda against named type with the criteria that decide; selection mechanisms
  compared (map, sealed switch, injected list, `ServiceLoader`) with their failure modes; the
  constants-are-configuration test; and the shared contract test. Read when choosing a mechanism.
- [Worked example](references/worked-example.md) — shipping cost calculation taken from a growing
  if-else to lambdas, then to named strategies when logging, metrics and a `supports` check were
  needed, with unknown-method handling, an illustrative shared-state race, and the
  contract test. 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 →