Skip to content

Expert · Design patterns, JVM internals and interviews · topic 57 of 60 · 30 min

Common design patterns

Explanation

Design patterns are named, proven solutions to common design problems. Java developers meet Singleton (one instance), Factory (create objects without exposing which class), Builder (create objects with many optional fields readably), Strategy (swap algorithms) and Observer (notify many listeners of an event) constantly, including inside Spring itself.

Why patterns?

Patterns give teams a shared vocabulary: saying "use a Strategy here" communicates a whole design in two words. They come from the 1994 "Gang of Four" book and decades of practice. Learn the problem each solves; do not force them into code that does not need them.

Singleton: exactly one instance

java
public enum AppConfig {          // the simplest thread-safe singleton
    INSTANCE;
    private final String region = "ap-south-1";
    public String region() { return region; }
}
AppConfig.INSTANCE.region();
In Spring apps you rarely write singletons yourself: beans are singletons by default.

Classic singletons with a static getInstance() need care with threads (double-checked locking with volatile, or the holder-class idiom). Singletons are global state, which makes testing harder; prefer dependency injection.

Factory: hide which class is created

java
interface Notifier { void send(String to, String msg); }
class SmsNotifier implements Notifier { public void send(String t, String m) { … } }
class EmailNotifier implements Notifier { public void send(String t, String m) { … } }

class NotifierFactory {
    static Notifier forChannel(String channel) {
        return switch (channel) {
            case "sms" -> new SmsNotifier();
            case "email" -> new EmailNotifier();
            default -> throw new IllegalArgumentException("Unknown channel: " + channel);
        };
    }
}

Builder: many optional fields

java
Order order = Order.builder()
        .customer("Asha")
        .item("Kurta", 1)
        .item("Dupatta", 2)
        .giftWrap(true)
        .deliveryNote("Call before arriving")
        .build();                     // validates and creates an immutable Order
Readable compared with new Order("Asha", items, true, null, null, "Call before arriving", false). Lombok's @Builder can generate this.

Strategy: swap an algorithm

java
interface FareStrategy { long fare(int km); }
class SleeperFare implements FareStrategy { public long fare(int km) { return 50 + km * 1; } }
class AcFare implements FareStrategy { public long fare(int km) { return 150 + km * 3L; } }

class Ticketing {
    private final FareStrategy strategy;
    Ticketing(FareStrategy strategy) { this.strategy = strategy; }
    long price(int km) { return strategy.fare(km); }
}
// With lambdas: FareStrategy tatkal = km -> 300 + km * 4L;

Observer: notify many listeners

java
interface OrderListener { void onPlaced(Order o); }
class OrderEvents {
    private final List<OrderListener> listeners = new ArrayList<>();
    void subscribe(OrderListener l) { listeners.add(l); }
    void placed(Order o) { listeners.forEach(l -> l.onPlaced(o)); }
}
events.subscribe(o -> sms.send(o.phone(), "Order placed"));
events.subscribe(o -> inventory.reserve(o));
Spring's ApplicationEventPublisher and @EventListener implement this pattern.
PatternWhere you see it in Java/Spring
SingletonSpring beans (default scope), Runtime.getRuntime()
FactoryList.of, Calendar.getInstance, BeanFactory
BuilderStringBuilder, HttpRequest.newBuilder(), Lombok @Builder
StrategyComparator passed to sort
ObserverEvent listeners, Spring application events
Template methodJdbcTemplate, abstract classes (module 5)
ProxySpring @Transactional and AOP wrap your beans in proxies
Careful: Pattern overuse is real: an AbstractSingletonProxyFactoryBean for a 200-line app is a joke for a reason. Use a pattern when its problem appears (many optional constructor arguments → Builder; growing if/else on types → Strategy), not to show you know it.
Think of it like this: Design patterns are like standard dance steps: once two dancers both know the "waltz", they can perform together without discussing every move. In code, "Builder" or "Observer" tells a teammate the whole shape at once.
Tip: For interviews, prepare one real example per pattern, plus how Spring uses it (Proxy for @Transactional is a favourite follow-up).

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Common design patterns · 1/6

Design patterns

In this lesson you will learn five design patterns every Java developer meets.

Prefer a video by a teacher? Find free videos on “java design patterns singleton factory builder strategy observer examples” on YouTube ↗

In real life: Payment strategies at checkout

A ticket-booking platform supports UPI, cards, net banking and wallets, each with different fees and flows. Each method is a PaymentStrategy; a factory picks one from the user's choice; an observer publishes "payment completed" so the ticket service, the SMS service and analytics react independently.

java
PaymentStrategy strategy = PaymentFactory.forMode(request.mode());   // Factory
Receipt r = strategy.pay(request.amountPaise());                      // Strategy
events.publish(new PaymentCompleted(r));                              // Observer

Practice (0/3 done)

Task 1 · Question

A constructor has 9 parameters, 6 of them optional. Which pattern helps most?

Task 2 · Code · Javascript

The Strategy pattern in JavaScript, which runs here: write fareFor(strategyName, km) using an object of strategy functions: sleeper = 50 + km, ac3 = 150 + 3 × km, tatkal = 300 + 4 × km. Unknown strategies throw an Error "Unknown class". Do not use if/else or switch on the name; look the function up in the object.

Task 3 · Practice

Implement an OrderEvents class (Observer) in Java with subscribe(OrderListener) and placed(Order). Register three listeners with lambdas: one prints "SMS sent", one reduces stock in a Map, one adds to a daily counter. Then write an immutable Order with a Builder (customer required, giftWrap and deliveryNote optional) that validates in build().

Quick quiz

Question 1

1.Which pattern does Comparator passed to list.sort represent?

Question 2

2.What is the simplest thread-safe singleton in Java?

Question 3

3.Spring implements @Transactional by wrapping beans in a…

Question 4

4.Observer is useful when…

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which pattern does Comparator passed to list.sort represent?

Answer: Strategy

It plugs in the comparison algorithm.

What is the simplest thread-safe singleton in Java?

Answer: An enum with one constant

The JVM guarantees enum constants are created once.

Spring implements @Transactional by wrapping beans in a…

Answer: Proxy

Proxies intercept calls to start and commit transactions.

Observer is useful when…

Answer: Many independent parts must react to one event

Publish once, many subscribers react.

Which annotation creates a bean from a method in a configuration class?Related

Answer: @Bean

@Bean methods inside @Configuration classes.

From Spring and dependency injection

How do you make a field private in Dart?Related

Answer: Start its name with _

Underscore names are library-private.

From Classes and constructors

What does == compare for two data class objects?Related

Answer: Their property values

Data classes generate equals based on properties.

From Data, enum and sealed classes, and objects

What makes a class field private?Related

Answer: A leading #

#name fields are truly private; _name is only a naming convention.

From Classes

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Design patterns, JVM internals and interviews” before its exam: JVM memory and garbage collection, Java interview questions, Projects and a Java career.
  2. Module 12 exam: Design patterns, JVM internals and interviews · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. 60 topics left in the course before the final exam.

← Previous: SOLID principles