Skip to main content

Java Design Patterns Overview

The Gang of Four (GoF) defined 23 design patterns across three categories: Creational (how objects are created), Structural (how objects are composed), and Behavioral (how objects communicate). Java developers encounter a core subset of ~15 of these daily — in the JDK itself (List.of(), InputStream, Comparator), in Spring AOP proxies, in JdbcTemplate, and in @EventListener. This page gives you a scannable reference for all 15.

Key Concepts at a Glance

Creational Patterns

  • Singleton: Ensures one instance per JVM. Use the Initialization-on-Demand Holder idiom or enum. Spring @Component beans are singletons by default.
  • Builder: Separates the construction of a complex object from its representation. Use for objects with many optional fields (UserProfile.builder()...build()). Lombok @Builder generates the boilerplate.
  • Factory Method: Defines an interface for creating an object but lets subclasses decide which class to instantiate. Static factory methods (List.of(), Optional.of()) are the most common Java idiom.
  • Abstract Factory: Creates families of related objects without specifying concrete classes. Spring @Profile with different @Configuration classes is the idiomatic Java equivalent.
  • Prototype: Creates new objects by copying an existing one. Prefer copy constructors over Cloneable. Spring @Scope("prototype") creates a new bean instance per injection point.

Structural Patterns

  • Decorator: Wraps an object to add behavior, implementing the same interface. Java I/O (BufferedInputStream wrapping FileInputStream) is the textbook example. Spring Security filter chain is a behavioral decorator chain.
  • Adapter: Converts the interface of a class into another interface clients expect. Use composition (Object Adapter) over inheritance (Class Adapter). InputStreamReader adapts InputStreamReader.
  • Facade: Provides a simplified interface to a complex subsystem. JdbcTemplate, RestTemplate, and RedisTemplate are Facades over low-level connection/transaction boilerplate.
  • Composite: Composes objects into tree structures representing part-whole hierarchies. Used for file systems, UI component trees, and Spring Security CompositeAuthorizationManager.
  • Proxy: Provides a surrogate that controls access to another object. JDK dynamic proxy requires an interface; CGLIB proxies concrete classes. Spring AOP uses proxies for @Transactional, @Cacheable, and @Async.

Behavioral Patterns

  • Strategy: Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Replaces if/else chains. Comparator is the canonical JDK Strategy. Inject via Spring @Qualifier or a Map<String, Strategy> registry.
  • Observer: When one object's state changes, all dependents are notified. Spring ApplicationEventPublisher + @EventListener is the idiomatic implementation. @TransactionalEventListener(AFTER_COMMIT) fires after the DB transaction commits.
  • Command: Encapsulates a request as an object, enabling undo/redo, queuing, and logging. Runnable/Callable are built-in Command interfaces. Spring Batch Step is a Command.
  • Template Method: Defines the skeleton of an algorithm in a base class, deferring some steps to subclasses. JdbcTemplate.query() uses this via callback (you supply the RowMapper; JdbcTemplate owns the connection lifecycle).
  • Chain of Responsibility: Passes a request along a chain of handlers until one handles it. Spring Security's FilterChainProxy is the canonical Java example. Logger hierarchy in java.util.logging is another.
  • State: Allows an object to alter its behavior when its internal state changes. Models FSMs (e.g., Order lifecycle: Pending → Paid → Shipped). Spring Statemachine provides a production-ready implementation.

Quick-Reference Table

PatternCategoryParticipantsJava / Spring Example
SingletonCreationalInstanceenum singleton; Spring scoped beans
BuilderCreationalProduct, Builder, DirectorLombok @Builder; StringBuilder
Factory MethodCreationalCreator, ProductList.of(), Optional.of(), Spring @Bean
Abstract FactoryCreationalAbstractFactory, product familiesSpring @Profile configuration classes
PrototypeCreationalPrototype, ClientCopy constructor; Spring @Scope("prototype")
DecoratorStructuralComponent, ConcreteDecoratorBufferedInputStream; Spring Security filters
AdapterStructuralTarget, Adaptee, AdapterInputStreamReader; Feign client wrappers
FacadeStructuralFacade, subsystem classesJdbcTemplate, RestTemplate
CompositeStructuralComponent, Leaf, CompositeFile system; CompositeAuthorizationManager
ProxyStructuralSubject, RealSubject, Proxyjava.lang.reflect.Proxy; Spring AOP
StrategyBehavioralContext, StrategyComparator; Spring @Qualifier strategies
ObserverBehavioralSubject, Observer@EventListener; @TransactionalEventListener
CommandBehavioralCommand, Invoker, ReceiverRunnable; Spring Batch Step
Template MethodBehavioralAbstractClass, ConcreteClassJdbcTemplate.query(RowMapper)
Chain of ResponsibilityBehavioralHandler, chainSpring Security FilterChainProxy
StateBehavioralContext, State, concrete statesOrder FSM; Spring Statemachine

Learning Path

Suggested reading order for a returning Java developer:

  1. Singleton Pattern — foundational creational pattern; understand thread-safety idioms before all others
  2. Builder Pattern — used constantly in modern Java (Lombok, records, DTOs)
  3. Factory Method Pattern — powers Spring @Bean and half the JDK API; understand static factory names
  4. Proxy Pattern — essential for understanding Spring AOP, @Transactional, and @Cacheable
  5. Decorator Pattern — once Proxy is clear, Decorator reinforces the wrapper idiom with a different intent
  6. Strategy Pattern — the most practically useful behavioral pattern; replaces conditionals in business logic
  7. Observer Pattern — Spring Events system; crucial for decoupled async workflows
  8. Template Method Pattern — explains why JdbcTemplate, RestTemplate, and all Spring *Template classes are designed the way they are
  9. Adapter Pattern — integration patterns; wrapping third-party SDKs
  10. Chain of Responsibility Pattern — completes the picture of Spring Security's filter pipeline

Top 5 Interview Questions

Q1: What is the difference between Proxy and Decorator? They look structurally identical. A: Structurally they are identical — both wrap an object implementing the same interface. The difference is intent. A Decorator adds new behavior or enhances the object's capabilities (e.g., adding buffering to a stream). A Proxy controls access to the object — it can add authorization checks, lazy initialization, caching, or remote access without changing what the object does. In practice, Spring's AOP proxies often blur this line by both enhancing (caching) and controlling (security) access.

Q2: Why does calling a @Transactional method from the same class not start a transaction? A: Spring implements @Transactional via a proxy — when an external caller calls service.save(), they call the proxy, which opens a transaction and then delegates to the real bean. However, when save() calls this.internalMethod(), this refers to the real bean object, not the proxy. The proxy is bypassed, so no transaction is started. The fix is to self-inject the bean (or restructure so the @Transactional method is called from outside the class).

Q3: When would you choose Factory Method over Abstract Factory? A: Factory Method creates a single product and lets subclasses decide the concrete type — it is about one class hierarchy (Notification → EmailNotification). Abstract Factory creates families of related products — it is about coordinating multiple class hierarchies (e.g., a ThemeFactory that produces a matching Button, TextField, and ScrollBar all in the same style). If your problem is "which one implementation of this interface?", use Factory Method. If your problem is "which consistent set of related implementations?", use Abstract Factory.

Q4: What is the Strategy pattern and how does Spring's dependency injection enable it? A: Strategy defines a family of interchangeable algorithms behind a common interface, selecting one at runtime without changing the client. In Spring, you implement each algorithm as a @Component and inject the desired one via @Qualifier, profiles, or a Map<String, Strategy> registry. The context class (e.g., OrderService) depends on the ShippingCalculator interface and never imports a concrete class — Spring's DI wires in whichever strategy the configuration dictates.

Q5: What is the Template Method pattern and how does JdbcTemplate apply it without inheritance? A: Template Method defines the skeleton of an algorithm in a base class — some steps are fixed (common to all callers) and some are abstract (overridden by subclasses). JdbcTemplate applies the pattern via callbacks instead of inheritance: the fixed steps are: acquire connection → create PreparedStatement → bind parameters → execute → close everything (even on exception). The varying step — what to do with each row — is passed in as a RowMapper lambda. You provide the mapping logic; JdbcTemplate owns the lifecycle. This is the modern, functional style of Template Method — no subclassing required.


All Notes in This Domain

NoteCategoryDescription
Singleton PatternCreationalThread-safe single-instance idioms: Holder, Enum, Spring @Component.
Builder PatternCreationalFluent construction; Effective Java idiom; Lombok @Builder; Director.
Factory Method PatternCreationalSubclass-driven creation; static factories; Spring @Bean factory methods.
Abstract Factory PatternCreationalFamilies of related objects; Spring @Profile as factory family.
Prototype PatternCreationalClone via copy constructor; Spring prototype scope; registry pattern.
Decorator PatternStructuralWrap to add behavior; Java I/O; Spring Security filter chain.
Adapter PatternStructuralBridge incompatible interfaces; object vs class adapter; legacy integration.
Facade PatternStructuralSimplified subsystem interface; JdbcTemplate; RestTemplate.
Composite PatternStructuralPart-whole trees; file systems; recursive operations.
Proxy PatternStructuralControl access; JDK dynamic proxy; CGLIB; Spring AOP.
Strategy PatternBehavioralInterchangeable algorithms; Comparator; Spring DI registry.
Observer PatternBehavioralNotify on state change; Spring events; @TransactionalEventListener.
Command PatternBehavioralRequest as object; undo/redo; Runnable; Spring Batch.
Template Method PatternBehavioralAlgorithm skeleton; JdbcTemplate callback; Spring Security filters.
Chain of Responsibility PatternBehavioralHandler chain; Spring Security FilterChainProxy.
State PatternBehavioralFSM; Order lifecycle; Spring Statemachine.