Java Omnibus
OOAD & Architecture / Design principles / DRY, KISS, YAGNI, and Law of Demeter
Design Principles Java Order Management
Design Principles

These lightweight principles help you resist accidental complexity before it hardens into architecture.

Not every design principle needs a full pattern catalog behind it. DRY, KISS, YAGNI, and the Law of Demeter are smaller heuristics, but they show up constantly in design reviews. Together they help teams avoid duplication, unnecessary complexity, premature abstraction, and brittle object navigation.

Why This Topic Matters

Why it matters in real Java systems

In e-commerce systems under delivery pressure, duplication and overengineering often appear side by side. One service copies validation logic in three places, while another introduces abstractions for features that may never exist. These heuristics help keep the model simpler and more resilient.

Core Explanation

The design idea behind this topic

DRY is most useful when it removes duplicate business knowledge, not when it aggressively extracts every repeated line. KISS reminds you that understandable designs often outperform clever ones. YAGNI protects the system from speculative complexity. The Law of Demeter helps limit fragile navigation through object graphs.

These heuristics often work together. A team that ignores YAGNI may create abstractions too early. A team that ignores Demeter may build brittle chains of calls. A team that over-applies DRY may produce abstractions so generic that readability collapses.

Used well, these principles keep OOAD grounded in actual needs.

Concept Breakdown

Key ideas to hold onto

Concept

DRY

Duplicate knowledge is more dangerous than duplicate syntax because it creates multiple sources of truth.

Concept

KISS and YAGNI

Prefer the simplest design that meets the current need, and do not build speculative structure without evidence.

Concept

Law of Demeter

Objects should collaborate through nearby, meaningful relationships instead of reaching deep into internal structure.

Java Example

Java example in the Order Management domain

Java example: avoiding deep reach-through in order delivery
package org.javaomnibus.ecommerce.principles;

public final class NotificationComposer {
    public String compose(Order order) {
        return "Order " + order.id() + " will be delivered to " + order.deliveryCity();
    }
}

final class Order {
    private final Shipment shipment;
    private final String id;

    Order(String id, Shipment shipment) {
        this.id = id;
        this.shipment = shipment;
    }

    String id() {
        return id;
    }

    String deliveryCity() {
        return shipment.deliveryCity();
    }
}

record Shipment(String deliveryCity) {}
Code Walkthrough

Step by step

  1. NotificationComposer does not reach through order to shipment to address to city.
  2. Order exposes a meaningful method in its own language, reducing deep navigation.
  3. This keeps callers less coupled to internal structure and makes future refactoring easier.
  4. The example is also simple, reflecting KISS rather than speculative abstraction.
Real-World Usage

Where this shows up in practice

  • Validation, notification, and pricing flows where duplicate business knowledge tends to spread
  • Avoiding overdesigned extension points before product variation is real
  • Reducing train-wreck call chains in rich domain models
Trade-Offs

When not to over-apply it

These heuristics can conflict. Removing duplication too early may hurt readability. Avoiding all abstraction may create repeated rules. The goal is disciplined simplicity, not rigid slogans.

Common Mistakes

Frequent mistakes to watch for

  • Abstracting too early in the name of DRY
  • Using YAGNI as an excuse to ignore obvious design pressure
  • Treating KISS as a reason to keep responsibilities mixed together
  • Confusing Demeter with zero collaboration between objects
Related Pages

Related concepts


What To Read Next