Java Omnibus
OOAD & Architecture / Architectural Styles / Onion Architecture
Onion Domain-Centered Java Dependencies
Architectural Styles

Onion architecture makes one thing unmistakable: the domain belongs at the center, and everything else should orbit around it.

Onion Architecture emphasizes concentric dependency direction. The domain model sits in the center. Around it come application services and use cases. Infrastructure and interfaces stay outside. It overlaps strongly with hexagonal and clean architecture, but its teaching strength is how clearly it visualizes dependency direction.

Why This Topic Matters

Why it matters in real Java systems

In an order domain with returns, refunds, shipment policies, and pricing rules, the most stable knowledge is often business knowledge. Onion architecture protects that center from web, database, and framework churn.

Core Explanation

The main architectural idea

The onion metaphor makes architecture concrete. The core contains the most stable business concepts. Each outer ring depends inward, never the other way around. This creates a very explicit mental model for dependency direction and often pairs naturally with rich domain modeling.

Where hexagonal architecture talks about ports and adapters, onion architecture talks more visually about the center and the rings around it. In practice, many systems mix the language of both.

Concept Breakdown

Key ideas to keep in mind

Concept

Center

Domain entities, value objects, policies, and invariants that should outlive tooling decisions.

Concept

Middle rings

Use cases and application orchestration that coordinate the domain without owning the domain’s meaning.

Concept

Outer rings

Web controllers, databases, queues, and external integrations that should remain replaceable.

Diagram in words

Diagram in words

Imagine the rings: at the center sit Order, Money, and ShipmentPolicy. Around that sits PlaceOrderUseCase. Around that are controllers, repositories, brokers, and message adapters. All code should depend inward toward the business center.
Java Example

Java example in the Order Management domain

Java example: domain policy staying in the center
package org.javaomnibus.ecommerce.domain;

public final class ShipmentPolicy {
    public boolean canShip(Order order) {
        return order.isPaid() && !order.isCancelled();
    }
}

package org.javaomnibus.ecommerce.application;

public final class ShipOrderUseCase {
    private final ShipmentPolicy shipmentPolicy;
    private final ShipmentPort shipmentPort;

    public ShipOrderUseCase(ShipmentPolicy shipmentPolicy, ShipmentPort shipmentPort) {
        this.shipmentPolicy = shipmentPolicy;
        this.shipmentPort = shipmentPort;
    }
}
Code Walkthrough

Step by step

  1. ShipmentPolicy belongs in the domain center because it expresses business rules.
  2. The use case depends on the policy and an outward-facing port.
  3. Infrastructure is not needed to understand the shipping rule itself.
  4. That separation is what onion architecture tries to make obvious.
Real-World Usage

Where this helps in practice

  • Rich domain models with important invariants
  • Systems where business logic should outlive frameworks and persistence choices
  • Teams teaching dependency direction visually and conceptually
Trade-Offs

Trade-offs and when not to overuse it

  • Onion architecture is powerful when the domain is rich, but can feel heavy for simple CRUD systems.
  • It also requires discipline so the center remains truly framework-free.
Common Mistakes

Frequent mistakes to watch for

  • Putting orchestration or repository logic into the domain center
  • Using the onion diagram but still letting domain code import frameworks
  • Treating concentric packaging as enough without enforcing dependency rules
  • Forcing rich domain structure where the problem is mostly simple data processing
Related Pages

Related concepts


What To Read Next