Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
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
  • Authors
  • 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
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Java Clean Functions

ASecurity

Enforces method design in Java 21+ — small methods that do one thing, at most three parameters, no boolean flag arguments, no null returns or arguments, and command-query separation. Use when writing or refactoring Java methods and constructors, and when the code shows long methods, parameter lists of four or more, boolean flags, deep nesting, output parameters, or methods returning null. Also trigger on: private helpers placed above the public methods that call them, a class that must be rea...

2 stars
0 votes
0 copies
1 views
Added 9/19/2026
developmentgojavanoderefactoringapi

Works with

cliapi

Security Analysis

A100/100

Scanned 9/19/2026

$npx -y skills add CasLubbers/code-design-skills --skill java-clean-functions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Java Clean Functions?

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

Security grade badge for Java Clean Functions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/caslubbers-java-clean-functions/badge)](https://www.skillsdirectory.com/skills/caslubbers-java-clean-functions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: java-clean-functions
description: Enforces method design in Java 21+ — small methods that do one thing, at most three parameters, no boolean flag arguments, no null returns or arguments, and command-query separation. Use when writing or refactoring Java methods and constructors, and when the code shows long methods, parameter lists of four or more, boolean flags, deep nesting, output parameters, or methods returning null. Also trigger on: private helpers placed above the public methods that call them, a class that must be read bottom-up, a method mixing orchestration with low-level detail, or asks about the stepdown rule, "should this read like a book", "what order should these methods go in".
---

# Clean methods in Java

## One thing, one level of abstraction

A method should read as a single idea. Mixed levels — orchestration next to byte fiddling — is the clearest sign it is doing two jobs.

```java
// Bad — orchestration, HTTP, parsing, and persistence in one place
public void syncOrders() {
    var client = HttpClient.newHttpClient();
    var request = HttpRequest.newBuilder(URI.create(url)).build();
    var response = client.send(request, BodyHandlers.ofString());
    var node = mapper.readTree(response.body());
    for (var item : node.get("orders")) {
        var order = new Order(item.get("id").asText(), item.get("total").asDouble());
        jdbc.update("INSERT INTO orders ...", order.id(), order.total());
    }
}

// Good — each step is nameable and testable
public void syncOrders() {
    var payload = fetchOrders();
    var orders = parseOrders(payload);
    orderRepository.saveAll(orders);
}
```

## The stepdown rule: the class reads top-down

A class should read like a narrative. Public API first, then the private methods it calls, in call
order — the reader descends one level of abstraction at a time and stops when they know enough.

```java
// Good — the story, then the details underneath it
public final class OrderExporter {

    public String export(List<Order> orders) {
        return orders.stream().map(this::toRow).collect(joining("\n"));
    }

    private String toRow(Order order) {
        return order.fields().stream().map(this::escapeQuotes).collect(joining(","));
    }

    private String escapeQuotes(String value) {
        return value.replace("\"", "\"\"");
    }
}
```

Fields at the top, constructors next, then public methods, then the private helpers each one calls.
A private helper used by two public methods goes below both.

This is why one-level-of-abstraction matters practically: a method mixing orchestration with
character-level detail cannot be placed in the ordering, because it belongs at two levels at once.
That is the signal to split it. If a whole class resists the ordering, it has more than one
responsibility.

## Three parameters, then stop

```java
// Bad
public Reservation book(String guest, LocalDate from, LocalDate to,
                        int guests, boolean breakfast, String notes) { ... }

// Good — the arguments were an object all along
public Reservation book(BookingRequest request) { ... }

public record BookingRequest(
    String guest, DateRange stay, int guests, boolean breakfast, String notes) {}
```

Records make parameter objects cheap: one line, immutable, with `equals`, `hashCode`, and `toString` supplied. Grouping parameters that always travel together is not overhead, it is the missing concept.

Constructors with many required fields are the one place a builder still earns its keep — but check first whether the object is doing too much.

## No boolean flags

A flag parameter says the method has two behaviours.

```java
// Bad — the call site is unreadable: report(data, true, false)
public Report generate(Data data, boolean detailed, boolean includeArchived)

// Good
public Report generateSummary(Data data)
public Report generateDetailed(Data data)
```

If the flag genuinely selects a mode, an enum names it: `generate(data, Detail.FULL)`.

## Guard clauses over nesting

```java
// Bad
public void process(Order order) {
    if (order != null) {
        if (order.isValid()) {
            if (!order.isProcessed()) {
                doWork(order);
            }
        }
    }
}

// Good
public void process(Order order) {
    if (!order.isValid()) {
        throw new IllegalArgumentException("invalid order: " + order.id());
    }
    if (order.isProcessed()) {
        return;
    }
    doWork(order);
}
```

Handle the exceptional path first and return; keep the real work at one indentation level.

## Never return null

```java
// Bad — every caller must remember to check
public User findUser(String id) { return null; }

// Good
public Optional<User> findUser(String id) { ... }
public List<Order> ordersFor(String id) { return List.of(); }  // empty, not null
```

`Optional` belongs on return types. Do not use it for fields or parameters — an overload or a required argument is clearer. And do not accept `null` arguments as a design: an overload beats a nullable parameter.

## Command-query separation

A method either returns a value or changes state, not both.

```java
// Bad — did it set something, or ask something?
if (setAttribute("username", "alice")) { ... }

// Good
if (hasAttribute("username")) {
    setAttribute("username", "alice");
}
```

Fluent builders returning `this` are the accepted exception.

## No output parameters

Mutating an argument to communicate a result hides the effect from the signature.

```java
// Bad
public void appendFooter(StringBuilder report)

// Good
public String withFooter(String report)
```

Prefer returning a new value. Records and `List.copyOf` make immutable results cheap.

## Prefer exceptions to error codes, and be specific

Throw a meaningful exception rather than returning a status the caller can ignore. Unchecked exceptions for programmer error and unrecoverable conditions; a checked exception only when the caller has a genuine recovery path. Never swallow one:

```java
// Bad
try { risky(); } catch (Exception e) { }

// Good
try {
    risky();
} catch (IOException e) {
    throw new SyncFailedException("sync orders from " + url, e);  // cause preserved
}
```

## Delete dead methods

Unused private methods, methods kept "in case", and code reachable only from a deleted feature all go. Version control remembers them.

Attribution

CasLubbersCasLubbers
View sourceSee grades on GitHubMore from CasLubbers →
SSkills Directory ProSkills Directory

Get any skill into Claude in one click.

Download any skill as a ZIP for Claude.ai, Claude Desktop, or .claude/skills. $9/mo.

See Pro

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 Directory ProSkills Directory

Get any skill into Claude in one click.

Download any skill as a ZIP for Claude.ai, Claude Desktop, or .claude/skills. $9/mo.

See Pro

Related Skills

Clean Code

Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments

304955 votes

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.

285172 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.

2222 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 ...

10311 votes
View all in development →