Java Omnibus
OOAD & Architecture / Anti-patterns / Anti-Patterns in Java Systems
Anti-Patterns Java Order Management
Anti-Patterns

Anti-patterns matter because failure becomes easier to fix once you can name the shape of the failure precisely.

Teams usually do not build anti-patterns on purpose. They emerge through pressure, convenience, deadlines, and unclear boundaries. One class starts handling too much. Entities become passive records. Primitive values spread. Every change touches five places. Anti-patterns are useful not because labels are magical, but because clear names speed up diagnosis and refactoring judgment.

Why This Topic Matters

Why it matters in real Java systems

In a Java order-management system, anti-patterns appear quickly under real delivery pressure. Checkout logic collects new rules, payment flows scatter across layers, shipment state becomes stringly typed, and repeated edits create change fatigue. Anti-patterns help a team see that these are not isolated code smells. They are recurring structural failures that deserve a design response.

Core Explanation

The failure shape behind this anti-pattern

Anti-patterns are design failures that repeat across projects because they arise from common pressures: feature growth without model refinement, frameworks shaping the code too aggressively, weak domain concepts, or misplaced responsibility. A healthy anti-pattern discussion does not shame teams. It helps them choose better repair strategies.

For Java developers, the most useful anti-patterns are the ones that explain why code is becoming brittle even though every local change seemed reasonable. That is why this batch focuses on God classes, anemic domain models, shotgun surgery, feature envy, data clumps, and primitive obsession.

The goal is not to memorize jargon. The goal is to learn to see failure early enough that the code can still be rescued incrementally.

Concept Breakdown

Key signals to watch for

Signal

Failure patterns, not isolated bugs

Anti-patterns describe system-level or design-level recurring failure shapes that keep making change harder.

Signal

Useful because they guide response

Once you know you are dealing with an anemic model or a God class, your refactoring options become more focused.

Signal

They connect directly to principles

Most anti-patterns are easier to explain when you connect them back to cohesion, responsibility, dependency direction, and domain modeling.

Java Example

Java example in the Order Management domain

Java example: several anti-pattern pressures gathering in one checkout flow
package org.javaomnibus.ecommerce.antipatterns;

public final class CheckoutService {
    public void checkout(CheckoutRequest request) {
        validateCustomer(request.customerId());
        validateAddress(request.shippingAddress());
        calculateDiscounts(request);
        reserveInventory(request.items());
        authorizePayment(request.paymentMethod(), request.total());
        saveOrder(request);
        createShipment(request);
        sendEmail(request.customerEmail());
        publishMetrics(request);
    }
}
Code Walkthrough

Step by step

  1. This one class is already showing God-class pressure because many unrelated responsibilities have gathered in one place.
  2. If request and related entities are only passive carriers, an anemic model problem may also be forming.
  3. As more branches get added, changes will likely spread across several unrelated methods and files.
  4. This is why anti-patterns are best read as recurring failure shapes, not as single-line mistakes.
Real-World Usage

Where this shows up in practice

  • Code reviews where the team senses brittleness but cannot yet explain it well
  • Refactoring planning for a legacy Java service layer
  • Architecture discussions where repeated change pain needs a shared vocabulary
Trade-Offs

How to respond proportionately

Teams can misuse anti-pattern labels as blunt criticism. The better use is diagnostic: identify the failure shape, then choose a proportionate fix grounded in the code and domain.

Common Mistakes

Frequent mistakes to watch for

  • Using anti-pattern terminology without showing concrete evidence in the code
  • Assuming every large class is automatically a God class
  • Treating anti-pattern discovery as the end rather than the start of refactoring
  • Ignoring the delivery pressures that caused the structure to emerge
Related Pages

Related concepts


What To Read Next