Open In App

Top 30 Java Design Patterns Interview Question

If you want to be a ​software developer or ​engineer, you need to know about design patterns. They’re like solutions to common problems in software design. In job interviews, employers ask about design patterns to see if you know what you’re doing. So, it’s important to be ready for those questions. We’ve made a list of 30 design pattern interview questions in Java. They cover different types of design patterns, like ones for creating things, organizing things, and making things work.

Top Java Design Patterns Interview Question

Q1: What is a design pattern in Java?

A design pattern refers to an established and verified solution for a repetitive issue in software development. It offers a standardized approach to solve common design problems and helps developers write maintainable, extensible, and reusable code.



Q2: Difference between design pattern and architectural pattern.

Q3: What are the types of design patterns in Java?

There are four types of design patterns in Java:

Q4: What is the Singleton design pattern in Java?

The singleton design pattern is a way to make sure that only one copy of a class exists. It is used when we want to have a global way to access this class. We use the singleton pattern when we need one object to control things in the whole system.



To implement the Singleton Pattern, we will need to:




public class Singleton {
    private static Singleton instance = null;
 
    private Singleton() {
        // private constructor
    }
 
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Q5: What is the Factory Method design pattern in Java?

The Factory Method pattern is a way to make things without saying exactly what kind of thing to make. It makes an outline for making things but let’s different kinds of things choose what kind of thing to make. This is helpful when you want to make things without worrying about how they are made.

To implement the Factory Pattern, we will need to:




public interface Animal {
    void speak();
}
 
public class Dog implements Animal {
    @Override public void speak()
    {
        System.out.println("Dog says: Bow Wow!");
    }
}
 
public class Cat implements Animal {
    @Override public void speak()
    {
        System.out.println("Cat says: Meow!");
    }
}
 
public interface AnimalFactory {
    Animal createAnimal();
}
 
public class DogFactory implements AnimalFactory {
    @Override public Animal createAnimal()
    {
        return new Dog();
    }
}
 
public class CatFactory implements AnimalFactory {
    @Override public Animal createAnimal()
    {
        return new Cat();
    }
}
 
public class AnimalClient {
    public static void main(String[] args)
    {
        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal();
        dog.speak();
 
        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal();
        cat.speak();
    }
}

Q6: What is the Observer design pattern in Java?

The Observer pattern is a way for objects to talk to each other. It’s like when you tell your friends about something, and they all know what’s going on. It’s used when many objects need to know when something happens to one object.

To implement the Observer Pattern, we will need to:




// Observer interface
interface Observer {
    void update(int value);
}
 
// Subject interface
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
 
// Concrete Observer class
class ConcreteObserver implements Observer {
    @Override
    public void update(int value) {
        System.out.println("Value changed to " + value);
    }
}
 
// Concrete Subject class
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private int value;
 
    public void setValue(int value) {
        this.value = value;
        notifyObservers();
    }
 
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
 
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
 
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(value);
        }
    }
}
 
// Client code
public class ObserverDemo {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
 
        // Create observers and register them
        Observer observer1 = new ConcreteObserver();
        subject.registerObserver(observer1);
 
        Observer observer2 = new ConcreteObserver();
        subject.registerObserver(observer2);
 
        // Modify the value of the subject, which triggers notifications to all observers
        subject.setValue(10);
 
        // Remove one observer and modify the value again
        subject.removeObserver(observer1);
        subject.setValue(20);
    }
}

Q7: What is the Adapter design pattern in Java?

The Adapter pattern helps different things to work together, even if they are not originally made to work together. It changes one thing to be like another thing so that they can work together. This is useful when there are things that cannot work together, but we still need them to work together.

To implement the Adapter Pattern, we will need to:




// Target interface
interface MediaPlayer {
    void play(String audioType, String fileName);
}
 
// Existing interface
interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}
 
// Existing class that implements the AdvancedMediaPlayer interface
class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: " + fileName);
    }
 
    @Override
    public void playMp4(String fileName) {
        // do nothing
    }
}
 
// Existing class that implements the AdvancedMediaPlayer interface
class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        // do nothing
    }
 
    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: " + fileName);
    }
}
 
// Adapter class that implements the MediaPlayer interface and contains an instance of the AdvancedMediaPlayer interface
class MediaAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedMediaPlayer;
 
    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer = new Mp4Player();
        }
    }
 
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMediaPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMediaPlayer.playMp4(fileName);
        }
    }
}
 
// Client code
public class AdapterDemo {
    public static void main(String[] args) {
        MediaPlayer mediaPlayer = new MediaAdapter("mp4");
        mediaPlayer.play("mp4", "movie.mp4");
 
        mediaPlayer = new MediaAdapter("vlc");
        mediaPlayer.play("vlc", "song.vlc");
    }
}

Q8: What is the Decorator design pattern in Java?

The Decorator pattern is a way to add new things to an object without changing how it looks or works. You make a new class that goes around the old object and adds new stuff to it.

To implement the Decorator Pattern, we will need to:




// Interface or abstract class
interface Car {
    void assemble();
}
 
// Concrete class that implements the Car interface
class BasicCar implements Car {
    @Override
    public void assemble() {
        System.out.println("Basic Car.");
    }
}
 
// Decorator class that implements the Car interface and contains an instance of the Car interface
class CarDecorator implements Car {
    protected Car car;
 
    public CarDecorator(Car car) {
        this.car = car;
    }
 
    @Override
    public void assemble() {
        car.assemble();
    }
}
 
// Concrete decorator class that adds new functionality to the original object
class SportsCarDecorator extends CarDecorator {
    public SportsCarDecorator(Car car) {
        super(car);
    }
 
    @Override
    public void assemble() {
        super.assemble();
        System.out.println("Adding features of Sports Car.");
    }
}
 
// Client code
public class DecoratorDemo {
    public static void main(String[] args) {
        Car basicCar = new BasicCar();
        basicCar.assemble();
 
        Car sportsCar = new SportsCarDecorator(new BasicCar());
        sportsCar.assemble();
    }
}

Q9: What is the Command design pattern in Java?

The Command pattern is a way to organize and control requests in a computer program. Instead of directly giving instructions, we use objects called commands to represent and execute our requests. This helps us use different requests with different clients, keep a record of previous requests, and even undo previous actions. We create an interface or a class to define how commands should be executed, and then create different classes to represent different types of commands.

To implement the Command Pattern, we will need to:




// Command interface
interface Command {
    void execute();
}
 
// Concrete command classes
class LightOnCommand implements Command {
    private Light light;
 
    public LightOnCommand(Light light) {
        this.light = light;
    }
 
    @Override
    public void execute() {
        light.turnOn();
    }
}
 
class LightOffCommand implements Command {
    private Light light;
 
    public LightOffCommand(Light light) {
        this.light = light;
    }
 
    @Override
    public void execute() {
        light.turnOff();
    }
}
 
// Receiver class
class Light {
    public void turnOn() {
        System.out.println("Light turned on");
    }
 
    public void turnOff() {
        System.out.println("Light turned off");
    }
}
 
// Invoker class
class RemoteControl {
    private Command command;
 
    public void setCommand(Command command) {
        this.command = command;
    }
 
    public void pressButton() {
        command.execute();
    }
}
 
// Client code
public class CommandDemo {
    public static void main(String[] args) {
        Light light = new Light();
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);
 
        RemoteControl remoteControl = new RemoteControl();
        remoteControl.setCommand(lightOn);
        remoteControl.pressButton();
 
        remoteControl.setCommand(lightOff);
        remoteControl.pressButton();
    }
}

Q10: What is the Iterator design pattern in Java?

The Iterator pattern helps us go through a list or a group of things. It keeps the way the group is organized a secret and gives us a way to get to each thing one after the other. It does this by creating a special tool called an Iterator that helps us move through the group.

To implement the Iterator Pattern, we will need to:




// Iterator interface
interface Iterator<T> {
    boolean hasNext();
    T next();
}
 
// Concrete iterator class
class ArrayIterator<T> implements Iterator<T> {
    private T[] array;
    private int currentIndex;
 
    public ArrayIterator(T[] array) {
        this.array = array;
        this.currentIndex = 0;
    }
 
    public boolean hasNext() {
        return currentIndex < array.length;
    }
 
    public T next() {
        return array[currentIndex++];
    }
}
 
// Aggregate class
class Array<T> implements Iterable<T> {
    private T[] array;
 
    public Array(T[] array) {
        this.array = array;
    }
 
    public Iterator<T> iterator() {
        return new ArrayIterator<T>(array);
    }
}
 
// Client code
public class IteratorDemo {
    public static void main(String[] args) {
        Integer[] array = {1, 2, 3, 4, 5};
        Array<Integer> integerArray = new Array<Integer>(array);
 
        Iterator<Integer> iterator = integerArray.iterator();
        while (iterator.hasNext()) {
            Integer element = iterator.next();
            System.out.println(element);
        }
    }
}

Q11: What is the Template Method design pattern in Java?

The Template Method pattern is a way to design things that lets you make a list of steps to do something, but some of the steps can be done in different ways. You start by making a base list of steps, then you make a main step that tells the other steps to run. Each step can be different, and they all work together to do the thing you want to do.

To implement the Template Pattern, we will need to:




// Abstract base class with a template method
abstract class AbstractClass {
    public final void templateMethod() {
        step1();
        step2();
        step3();
    }
 
    protected abstract void step1();
    protected abstract void step2();
    protected abstract void step3();
}
 
// Concrete subclass that provides specific implementations for the steps
class ConcreteClass extends AbstractClass {
    protected void step1() {
        System.out.println("ConcreteClass: step 1");
    }
 
    protected void step2() {
        System.out.println("ConcreteClass: step 2");
    }
 
    protected void step3() {
        System.out.println("ConcreteClass: step 3");
    }
}
 
// Client code
public class TemplateMethodDemo {
    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass();
        abstractClass.templateMethod();
    }
}

Q12: What is the Builder Method design pattern in Java?

The Builder design pattern is a way to build things step-by-step. It helps you make complicated things using a specific process. This pattern separates the building part from the final thing, so you can make different final things using the same process. The Builder pattern is useful when you want to make complicated things, but the process to make them is simple. It lets you make the thing little by little and then get the final thing when it’s done.

Here is an example of how the Builder Pattern might be implemented:




public class BuilderExample {
    public static void main(String[] args) {
        // create the director
        Director director = new Director();
 
        // create the builder
        Builder builder = new ConcreteBuilder();
 
        // construct the complex object
        director.construct(builder);
 
        // retrieve the finished product
        ComplexObject complexObject = builder.getResult();
    }
}
 
class ComplexObject {
    // fields for the complex object
}
 
class Director {
    public void construct(Builder builder) {
        // use the builder to construct the complex object
    }
}
 
abstract class Builder {
    // methods for constructing the complex object
    public abstract ComplexObject getResult();
}
 
class ConcreteBuilder extends Builder {
    private ComplexObject object = new ComplexObject();
 
    // methods for constructing the complex object
    public ComplexObject getResult() {
        return object;
    }
}

Q13: How many ways we you create a singleton pattern?

There are two ways of creating a Singleton pattern.

  1. Early Instantiation: It is responsible for the creation of instance at load time.
  2. Lazy Instantiation: It is responsible for the creation of instance when required.

Q14: Describe the strategy to design a pattern?

The following points should need to be taken care to describe the design pattern:

Q15: What is the decorator pattern in Java explain it with an example?

The decorator pattern is one of the popular Java design patterns. It is common because of its heavy usage in java.io (package). The Decorator Pattern uses composition in place of inheritance to extend the functionality of an object at runtime.

Example: BufferedReader and BufferedWriter

Q16: Difference between Strategy and State design Pattern in Java?

Both Strategy and State patterns have a similar structure. Their UML class diagram looks the same, but they have different purposes. The state design pattern is used to manage and define the state of an object, while the Strategy pattern is used to describe a set of an interchangeable algorithm.

Q17: What are the advantages of Composite Design Pattern in Java?

The composite design pattern helps people work together with things that might or might not be part of a group.

Advantages:

Q18: Describe the uses of the Composite Design Pattern.

Use cases:

Q19: What are Some Design Patterns used in the JDK library?

Some of the following design patterns are used in the JDK library:

Q20: Advantage of Builder design pattern in Java.

Q21: How to write Thread-safe Singleton in Java?

Q22: Is it possible to create a clone of a singleton object?

Yes, it is possible to create a clone of a singelton object

Q23: What is the proxy pattern, and what does it do?

It is also known as placeholder or surrogates. The term Proxy stands for an object representing another object. The proxy pattern provides a substitute or placeholder for another purpose to control access to it. According to Gangs of four (GOF), a Proxy Pattern “provides control for accessing the original object. “We can perform many security operations like hiding the information of the original object, on-demand loading, etc.

Q24: Explain some different type of proxies?

Protection proxy

It controls access to the real subject based on the condition.

Virtual proxies

It is a structural design pattern that falls under the category of proxy patterns. A proxy is an object that acts as an intermediary or placeholder for another object to control access to it.

Caching proxies

It is a type of proxy pattern that is used to improve the performance and efficiency of an application by storing and reusing previously fetched or computed data. It acts as an intermediary between a client and a target object, and its primary purpose is to cache data or results of expensive operations so that subsequent requests for the same data can be satisfied quickly from the cache rather than going to the target object or performing the computation again. Caching proxies are commonly used in various software systems, including web applications, databases, and distributed systems, to reduce latency and resource consumption.

Remote proxies

Remote proxies are used in distributed object communication. The remote proxy causes execution on the remote object by invoking a local object method.

Smart proxies

Smart proxies are used to implement log calls and reference counting to the object.

Q25: Explain the Chain of Responsibility Pattern, when it is used & their advantages.

It is a behavioral design pattern that allows you to pass requests along a chain of handlers. Each handler in the chain decides either to process the request or to pass it to the next handler in the chain. This pattern promotes loose coupling between the sender (client) of a request and its receivers (handlers), making it easier to add or remove handlers and change the order in which they process requests.

Advantages of the Chain of Responsibility pattern is:

Uses of Chain of Responsibility Pattern:

Q26: How Bridge Pattern is different from the Adapter Pattern?

Bridge Pattern focuses on separating abstraction and implementation hierarchies to allow them to evolve independently. It’s used to handle variations in both abstraction and implementation.

Adapter Pattern focuses on making two incompatible interfaces work together by providing a wrapper (adapter) that translates between them. It’s used to make existing classes collaborate when their interfaces don’t match.

Q27: What is the difference between the Dependency Injection and Service Locator Patterns?

Dependency Injection (DI) is a design pattern focused on managing and injecting dependencies into classes, promoting testability and loose coupling. It provides explicit and constructor-based or setter-based injection of dependencies.

Service Locator (SL) is a design pattern focused on centralizing the retrieval of services or components from a registry or locator object. It provides a centralized point for service location but doesn’t necessarily promote the same level of inversion of control or testability as Dependency Injection.

Q28: Explain the Intercepting Filter Design Pattern, components and its advantages?

The Intercepting Filter Design Pattern is a behavioral design pattern that allows you to preprocess and post-process requests and responses in a system by using a series of filters. Each filter performs a specific action or validation on the request or response as it flows through the system. This pattern is commonly used in web applications for tasks such as input validation, authentication, logging, and other cross-cutting concerns.

Components of Intercepting Filter Pattern are:

Advantages of Intercepting Filter Design Pattern:

Q29: Explain Data Access Object (DAO) Design Pattern?

The Data Access Object (DAO) Design Pattern is a structural pattern that provides an abstract interface for accessing and manipulating data stored in a database or other data storage systems. The primary goal of the DAO pattern is to separate the business logic from the data access logic, promoting a clean and maintainable architecture. It accomplishes this by encapsulating the data access code within a set of data access objects, thereby abstracting the details of how data is fetched or persisted.

Q30: what is the difference between Value Object (VO) and Java Data Object (JDO)?

VOs are a design pattern for representing data as immutable objects without identity, represents an abstract design pattern, that is used in conjunction with entity beans, JDBC and JDO.

JDOs is a technology and specification for persisting Java objects in a database, persistent technology that competes against entity beans. It allows to create POJO (plain old java objects) and persevere them to the database.

Conclusion

The top 30 Java design pattern interview questions covered a wide range of design principles, from creational to behavioral patterns, providing valuable insights for both experienced developers and job seekers. These patterns offer practical solutions for real-world software challenges, improving code quality and maintainability. Mastering these design patterns is essential for Java developers aiming to create efficient and adaptable solutions, regardless of project size or complexity.


Article Tags :