Java Omnibus
OOAD & Architecture / Microservices & Distributed Patterns / Decomposition by Subdomain and Capability
Decomposition DDD Capabilities Java
Microservices & Distributed Patterns

The best microservice boundary usually sounds like a business capability, not a technical convenience.

Teams often split systems by controllers, repositories, shared tables, or organization chart lines. Those decompositions feel fast at first but create constant cross-service coordination later. A stronger starting point is subdomain and capability: ordering, pricing, inventory, payments, fulfillment, and notifications each have different language, rules, and change rhythms.

Why This Topic Matters

Why it matters in real Java systems

In an Order Management system, the ordering team should not need to understand the internals of shipment routing, and the shipment team should not depend on pricing rules to evolve. Good decomposition creates local reasoning and reduces the number of cross-boundary decisions required for normal change.

Core Explanation

The main design idea

Decomposition by subdomain uses domain language to define service boundaries. Core capabilities protect the business differentiators. Supporting capabilities make core work possible. Generic capabilities are important but not unique to the business. A service boundary is healthy when it has coherent rules, clear ownership, and a low need for synchronous chatter with neighbors.

Capability-based decomposition is not the same as "one noun, one service." The right boundary often contains several closely related entities because the real question is transactional and conceptual cohesion, not vocabulary count.

Concept Breakdown

Key ideas to keep in mind

Concept

Own a capability

Ordering owns order lifecycle rules, not just order tables or order endpoints.

Concept

Keep data with behavior

If a rule changes together, the model and data that support it likely belong together.

Concept

Avoid layer-based splits

A 'user-service' or 'database-service' split often hides technical seams inside business workflows.

Boundary test questions

Boundary test questions

Question Healthy signal Warning sign
Does this capability have its own language?Ordering, payment, fulfillment terms differ naturallyOnly technical nouns separate the services
Can one team own the rules?Changes stay mostly localEvery change crosses multiple teams
Are the workflows mostly cohesive?Core transactions stay inside one boundaryEvery command triggers many synchronous calls
Can the data evolve independently?Schema and behavior change togetherServices still share conceptual ownership of the same data
Java Example

Java example in the Order Management domain

Java example: capability-oriented ports
package org.javaomnibus.orders.application;

public interface InventoryReservationPort {
    ReservationResult reserve(OrderId orderId, List<OrderLine> lines);
}

public interface PaymentCommandPort {
    AuthorizationResult authorize(OrderId orderId, Money amount);
}

public interface ShipmentPlanningPort {
    ShipmentPlan planShipment(OrderId orderId, DeliveryAddress address);
}
Code Walkthrough

Step by step

  1. Each port speaks in business capability terms rather than CRUD operations against shared data.
  2. That makes the collaboration language more stable and reveals where capability boundaries actually exist.
  3. If the boundaries are later implemented as services, the contracts still reflect business intent instead of technical leaks.
  4. This is decomposition as model design, not just deployment slicing.
Real-World Usage

Where this helps in practice

  • Splitting large monoliths by domain capability
  • Reorganizing teams around bounded contexts rather than UI screens or data tables
  • Evaluating whether a proposed service boundary is really a business capability
Trade-Offs

Trade-offs and when to be careful

  • Capability decomposition improves autonomy, but it can expose more integration points when workflows cross contexts.
  • A perfectly pure split is rare; the goal is better cohesion than the current shape, not theoretical perfection.
Common Mistakes

Frequent mistakes to watch for

  • Decomposing by database schema instead of business responsibility
  • Assuming every entity deserves its own service
  • Ignoring reporting and query needs until after the split
  • Creating a shared 'common service' that quietly becomes a new monolith
Related Pages

Related concepts


What To Read Next