Java Omnibus
OOAD & Architecture / OOA / OOD process / Responsibility-Driven Design in Java
OOA/OOD Process Java Order Management
OOA / OOD Process

Responsibility-driven design asks the most practical OOAD question: who should do this work?

Responsibility-driven design is where OOAD becomes sharply practical. Instead of asking which class should contain a method because of existing structure, you ask which object should own the behavior because of its role in the model. That shift prevents the slow drift toward utility-heavy and service-heavy Java designs.

Why This Topic Matters

Why it matters in real Java systems

Checkout, payment, shipment, refund, and notification flows often become easier to implement by centralizing logic in one service. They become harder to maintain for exactly the same reason. Responsibility-driven design helps distribute behavior according to domain meaning, orchestration role, and policy boundaries.

Core Explanation

The design idea behind this process step

Responsibility-driven design is closely related to cohesion, GRASP, and Tell, Don't Ask. It pushes you to assign behavior where it fits naturally, rather than where it is easiest to call from. In Java, that often means balancing rich domain behavior with focused application services and explicit policies.

One useful test is to narrate the workflow in plain language. If the story says, "the order decides," "the shipment transitions," or "the pricing policy calculates," that is usually a sign the design can carry those responsibilities directly rather than routing everything through one orchestration class.

The result is not always fewer classes. It is clearer ownership and less ambiguous behavior.

Concept Breakdown

Key ideas to keep in view

Concept

Information and behavior belong together

If an object has the facts required to enforce a rule, that is often a clue it should own the rule.

Concept

Use cases coordinate, domain objects protect

Application-level orchestration is valid, but it should not swallow every domain decision.

Concept

Policies deserve clear homes

Discounts, fraud checks, and reservation logic often belong in explicit policy or strategy objects.

Java Example

Java example in the Order Management domain

Java example: responsibility placed on the object that owns the rule
package org.javaomnibus.ecommerce.process;

public final class Order {
    private final Money total;
    private PaymentStatus paymentStatus = PaymentStatus.PENDING;

    public Order(Money total) {
        this.total = total;
    }

    public void authorizePayment(PaymentAuthorizer paymentAuthorizer, PaymentMethod paymentMethod) {
        PaymentResult paymentResult = paymentAuthorizer.authorize(total, paymentMethod);
        if (!paymentResult.approved()) {
            throw new IllegalStateException("Payment was not approved");
        }
        paymentStatus = PaymentStatus.AUTHORIZED;
    }
}

interface PaymentAuthorizer {
    PaymentResult authorize(Money amount, PaymentMethod paymentMethod);
}
Code Walkthrough

Step by step

  1. The payment authorizer performs the external authorization work.
  2. The order still owns what payment authorization means for its own state.
  3. This is responsibility-driven design in practice: collaborators help, but ownership remains clear.
  4. The object model stays meaningful instead of becoming a set of passive records around a procedural service.
Real-World Usage

Where this process step shows up in practice

  • Refactoring anemic domain models in long-lived Java systems
  • Design reviews where teams debate whether logic belongs in entities, use cases, or policies
  • Teaching developers how to separate orchestration responsibilities from domain responsibilities
Trade-Offs

When to be careful

Not every object should become highly behavioral. Some data-transfer boundaries remain intentionally simple. The key is to add responsibility where the domain actually benefits from protection and meaning.

Common Mistakes

Frequent mistakes to watch for

  • Putting all behavior into entities without distinguishing orchestration from domain logic
  • Leaving business rules in services because changing the model feels harder
  • Turning responsibility-driven design into a ban on application services
  • Ignoring collaboration costs when responsibilities are split too finely
Related Pages

Related concepts


What To Read Next