Boundary control
A style gives rules for what can depend on what, which is often the real architecture problem.
After objects, principles, UML, patterns, DI, and enterprise boundaries, the next design question is larger: how should the whole system be arranged? Architectural styles are the recurring shapes teams use to control dependencies, organize boundaries, and survive change over time.
In an Order Management platform, the same use cases can be arranged in very different ways. A layered system may optimize for clarity and team familiarity. A hexagonal system may prioritize infrastructure isolation. An event-driven system may favor decoupled flows and asynchronous scaling. The style you choose changes testing, deployment, coupling, and operational risk.
Architectural styles are not interchangeable paint jobs over the same design. They influence dependency direction, team boundaries, module ownership, operational complexity, and how easy it is to replace infrastructure or split the system later.
The purpose of this section is not to promote one fashionable style. It is to teach decision criteria. Many Java business systems are still well-served by layered or modular monolith designs. Some benefit from ports-and-adapters or clean boundaries. Some need event-driven collaboration. The right answer depends on forces, not trend pressure.
A style gives rules for what can depend on what, which is often the real architecture problem.
A good style helps the system change without forcing unrelated parts to change with it.
Every style buys something and costs something. Clarity comes from naming both sides honestly.
Use the overview, decision guide, and comparison pages to understand when a style helps and when it adds unnecessary complexity.
Layered, hexagonal, onion, clean, pipes and filters, and event-driven styles are explained through realistic Java examples.
This helps connect architectural styles to team size, deployment boundaries, and change rate.
These are often treated as synonyms. They overlap, but the emphasis and teaching model differ in useful ways.
package org.javaomnibus.ecommerce.application;
public final class PlaceOrderUseCase {
private final OrderStore orderStore;
private final PaymentPort paymentPort;
private final NotificationPort notificationPort;
public PlaceOrderUseCase(
OrderStore orderStore,
PaymentPort paymentPort,
NotificationPort notificationPort
) {
this.orderStore = orderStore;
this.paymentPort = paymentPort;
this.notificationPort = notificationPort;
}
public void place(PlaceOrderCommand command) {
Order order = Order.create(command.customerId(), command.lines());
paymentPort.capture(order.id(), order.total());
orderStore.save(order);
notificationPort.orderPlaced(order.id());
}
}