We Should Write Java Code Differently: Less Language, More Business

Published: (April 6, 2026 at 08:21 AM EDT)
6 min read
Source: Dev.to

Source: Dev.to

How Much of Your Code Is Actually About Your Business?

Open any Java service method. Count the lines.

  • How many describe what the business does?
  • How many are null checks, exception handling, try‑catch blocks, type conversions, logging boilerplate, and framework annotations?

In most codebases the answer is uncomfortable: technical ceremony dominates, and business logic hides between the scaffolding. A new developer can read the code and understand how it works — but not what it does or why.

The Real Problem: Language, Not Skill

It isn’t a skill problem; it’s a language problem. Java gives us powerful tools, but it doesn’t guide us toward using them in ways that preserve business meaning.

A Typical Service Method

// Process an order
public OrderResult process(OrderRequest request) {
    // 1️⃣ Validate the input
    //    (null checks, field validation, exception wrapping)

    // 2️⃣ Check inventory
    //    (try‑catch around HTTP call, retry logic, timeout handling,
    //     response parsing)

    // 3️⃣ Calculate pricing
    //    (more HTTP, more try‑catch, more parsing)

    // 4️⃣ Create the order
    //    (database call, transaction management, exception handling)

    // 5️⃣ Return the result
    //    (response mapping, error conversion)
}

Five business steps, but the code for each step is roughly 80 % technical handling and 20 % business intent. The scaffolding drowns out the signal.

What If the Technical Surface Disappeared?

Types as High‑Level Documentation

  • Result tells you the method can fail without looking at the implementation.
  • Option tells you the value might be absent.
  • Promise tells you it’s asynchronous.

The return type becomes the documentation; no Javadoc is needed to explain “this method might throw”.

Composition Operators as Business Statements

OperatorBusiness Meaning
flatMap“If the previous step succeeded, do this next.”
all()“These operations are independent; they have no ordering dependency and can execute in parallel.”

When you read all(checkInventory, calculatePricing), you instantly know the two steps don’t depend on each other. That’s domain knowledge encoded in structure.

Exhaustive Error Types

A sealed interface that lists every failure mode lets a business analyst read the error hierarchy and understand what can go wrong—without digging into implementation code. Errors become first‑class types that enumerate the business failure domain.

Structural Patterns, Not Creative Control Flow

  • Sequencer – “Do these things in this order.”
  • Fork‑Join – “Do these things in parallel, then combine results.”
  • Leaf – “A single operation with no sub‑steps.”

Developers don’t invent control flow; they select from a small set of patterns that map directly to business processes.

The Refactored, Business‑Centric Method

static OrderService orderService(InventoryService inventory,
                                 PricingService pricing) {
    return request -> inventory.check(request.items())
                               .flatMap(pricing::calculate)
                               .map(OrderResult::placed);
}

Three lines. Each line is a business step.
The technical ceremony—HTTP calls, serialization, retries, error handling—still exists, but it’s handled by the runtime and the type system, not by the developer in this method.

Read it aloud: “Check inventory. Then calculate pricing. Then create the order.”
That isn’t a description of the code. That is the code.

Why This Matters

Knowledge Transfer

  • When technical ceremony dominates:
    New team members learn the framework (annotations, configuration, exception handlers). That knowledge is framework‑specific and doesn’t transfer well.

  • When business logic dominates:
    New members learn the domain (operation dependencies, failure modes, valid states). That knowledge survives framework migrations, team changes, and technology shifts.

The original developer’s intent—the business reasoning behind the code—is preserved in the structure itself, not in drifting comments or stale documentation.

Most Language Features Are Unnecessary for Business Value

Java is a large language. Features like inheritance hierarchies, checked exceptions, mutable state, reflection, annotation processing, type‑erasure work‑arounds, synchronized blocks, and volatile fields are powerful—but they rarely help express business logic clearly.

The Small Subset That Actually Helps

FeatureTypical Use
RecordsImmutable data carriers
Sealed interfacesType‑safe alternatives / exhaustive error handling
Lambdas & method referencesComposition of steps
Pattern matchingDispatch based on domain types

The rest—tools that generate conference talks and blog posts about clever techniques—primarily serve technical ceremony, not business logic.

Benefits of a Minimal, Business‑Focused Subset

  1. Compressed learning curve – New developers only need to master the subset that carries business meaning.
  2. Predictable code – With one canonical way to express a concept, style debates disappear and focus shifts to the domain.
  3. Eliminated “which feature should I use?” decisions – The answer is always the same small set of constructs.

Bottom Line

When the technical surface shrinks to the point where it almost disappears, business logic becomes the dominant signal in the code. That makes the code:

  • Easier to read and understand.
  • More resilient to change.
  • Better at communicating the true intent of the system.

Focus on the language features that directly express business concepts, and let the runtime and type system handle the ceremony.

We Should Write Java Code Differently – Part 6

The implication is broader than one language. If Java’s business‑relevant subset is this small, adding more language features doesn’t increase business expressiveness—it only expands the technical surface that competes for attention with the business logic. Expressiveness comes from domain modeling, not from language syntax.

The Technical Part of the Code

  • Small – a handful of types and patterns, not a framework vocabulary
  • Standardized – the same patterns everywhere, no per‑developer style
  • Semantically meaningful – each construct maps to a business concept

The Business Part of the Code

  • Dominant – more visible than the technical scaffolding
  • Readable – a sequence of named operations, not a tangle of callbacks
  • Exhaustive – every failure mode visible, every dependency declared

When these two conditions are met, code becomes what it should have been from the start: an executable specification of what the business does.

This is the sixth article in the “We Should Write Java Code Differently” series.
Previous article: The DI Confusion.

0 views
Back to Blog

Related posts

Read more »

Um resumo sobre coesão e SRP

O que é uma classe coesa? Uma classe coesa é aquela que tem apenas uma responsabilidade. Classes coesas são menores, mais organizadas, fáceis de manter e reuti...

Global Variable VS Local Variable

Global Variable in Java Java does not support true global variables. Instead, it uses class‑level variables, which behave similarly. Types of Class‑Level Varia...

OpenJDK: Panama

Project Panama: Interconnecting JVM and native code We are improving and enriching the connections between the Java virtual machine and well‑defined but “forei...