Mediator Design Pattern in Java: Complete Guide with Examples

Five components in a UI form — a checkbox, a dropdown, two text fields, and a submit button — all need to react when each other changes. The checkbox enables the dropdown; the dropdown choice changes which text fields are required; the submit button enables only when all required fields are filled. If each component talks directly to the others, you end up with 5 × 4 = 20 direct dependencies. Add a sixth component and you need to update potentially five existing ones. The Mediator pattern replaces all those direct links with a single hub: components talk only to the mediator, and the mediator coordinates everyone.

The pattern is best understood as the opposite of tight coupling. Without it, N components need O(N²) connections. With it, N components each need exactly 1 connection to the mediator — O(N) total. The tradeoff is that the mediator itself becomes a concentrator of coordination logic, so it needs to be kept focused and testable.

Continue reading Mediator Design Pattern in Java: Complete Guide with Examples

Iterator Design Pattern in Java: Complete Guide with Examples

You have a BookShelf that stores books in an ArrayList internally. You want callers to be able to iterate over books without knowing it’s an ArrayList. Next month you might change it to a linked list or a tree structure sorted by author. If callers work directly with your internal list, every change to your storage structure breaks them. The Iterator pattern gives callers a stable traversal interface that survives any change to the underlying data structure.

This is one of the patterns you already use every day through Java’s for-each loop. Every class that implements Iterable<T> is participating in this pattern. Understanding the mechanics helps you write cleaner custom collections and explains why certain traversal approaches are more maintainable than others.

Continue reading Iterator Design Pattern in Java: Complete Guide with Examples

Command Design Pattern in Java: Complete Guide with Examples

Every text editor has Ctrl+Z. Every transaction system has rollback. Every task queue has deferred execution. All of them rely on the same underlying idea: wrap a request in an object so you can store it, pass it around, and undo it later. That’s the Command pattern. When an action becomes an object, everything you can do with objects — store in a collection, serialize to disk, execute at a scheduled time, replay in order, reverse — becomes available to your actions.

The pattern separates the code that decides to do something (the Invoker) from the code that knows how to do it (the Receiver) via a Command object that encapsulates the call. This separation is what makes undo possible: the command object knows both how to execute and how to reverse its own effect.

Continue reading Command Design Pattern in Java: Complete Guide with Examples

Chain of Responsibility Design Pattern in Java: Complete Guide

A support ticket comes in. Should it go to Level-1 support, Level-2 engineering, a senior architect, or the on-call incident team? The severity determines the right handler — but the code submitting the ticket shouldn’t need to know the routing rules. The Chain of Responsibility pattern lets you define a sequence of handlers, each deciding whether to handle a request or pass it to the next handler in the chain. The sender fires into the chain; the chain figures out who deals with it.

This pattern shows up in more places than you might expect: Java Servlet filters, Spring’s interceptor chain, Java’s logging framework, and every middleware pipeline in modern web frameworks all use the same structure. Understanding it from first principles makes those frameworks far less mysterious.

Continue reading Chain of Responsibility Design Pattern in Java: Complete Guide

Proxy Design Pattern in Java: Complete Guide with Examples

Your service holds a database connection that takes 200ms to open. On most requests you don’t need it — the data is already cached or the request is served from memory. With the Proxy pattern, you can give every caller a DatabaseConnection object at startup but only open the real connection the first time a query is actually executed. The caller’s code doesn’t change. The real connection object doesn’t change. The proxy sits in between and makes the decision.

Proxy is one of the most widely used patterns in enterprise Java. Every time you use Spring’s @Transactional, @Cacheable, or @Async, you’re working through a proxy. Hibernate’s lazy-loaded entities are proxies. Java’s java.lang.reflect.Proxy creates proxies dynamically at runtime. Understanding the pattern means understanding a large chunk of how modern frameworks work.

Continue reading Proxy Design Pattern in Java: Complete Guide with Examples

Flyweight Design Pattern in Java: Complete Guide with Examples

A game renders a forest of 100,000 trees. Each tree has a position, but also a species name, color values, and a texture bitmap that might be several megabytes. Storing that texture in every tree object would exhaust memory for any meaningful forest. The Flyweight pattern solves this by separating the data that’s unique to each object (position) from the data that’s shared across thousands of identical objects (species, texture) — and storing the shared part only once.

Flyweight is the most performance-oriented structural pattern in the GoF catalogue. It’s not about flexibility or interface design — it’s about fitting more objects into the same memory by eliminating duplication. When you know a large number of objects will share most of their state, Flyweight gives you a principled way to exploit that sharing.

Continue reading Flyweight Design Pattern in Java: Complete Guide with Examples

Facade Design Pattern in Java: Complete Guide with Examples

Converting a video file involves opening the source, detecting its codec, selecting a destination codec, reading bitrate data, converting the buffer, and fixing the audio tracks. Six steps across six classes. When your application needs to convert videos, it shouldn’t have to orchestrate all six steps every time — that knowledge belongs in one place. The Facade pattern packages complex multi-step workflows behind a simple interface, so callers do it in one line instead of six.

Unlike the Adapter (which translates an interface) or the Decorator (which adds behaviour to an interface), the Facade doesn’t change any interfaces at all. It just creates a new, simpler entry point to an existing subsystem. The subsystem stays unchanged and remains fully accessible to callers who need more control.

Continue reading Facade Design Pattern in Java: Complete Guide with Examples