Design patterns are a standard topic in senior software engineering interviews at Indian product companies. SOLID principles, creational patterns, structural patterns, and behavioral patterns are regularly tested in both written and discussion-based interview rounds. This guide covers design patterns interview questions for India in 2026.
SOLID principles
SOLID principles:
1. Single Responsibility Principle (S): A class should have only one reason to change — one responsibility, one job. Violation example: a class that handles user authentication AND sends email notifications AND logs events. Problem: a change to the email library requires modifying the auth class. Fix: split into AuthService, EmailService, AuditLogger. In practice: the most commonly violated principle; look for 'God classes' that do everything.
2. Open/Closed Principle (O): A class should be open for extension but closed for modification. Add new behaviour by adding new classes (extension), not by modifying existing ones. Violation example: a discount calculation method with a series of if/else branches for each discount type; adding a new discount type requires modifying the method. Fix: use the Strategy pattern — define a Discount interface; each discount type implements it; add new discounts by adding new classes.
3. Liskov Substitution Principle (L): Objects of a subclass should be substitutable for objects of the superclass without breaking the program. Violation example: Square extends Rectangle; if code sets width and height independently (valid for Rectangle), a Square (which must have equal width and height) breaks. Fix: do not force inheritance where it violates the substitution principle; prefer composition.
4. Interface Segregation Principle (I): Clients should not be forced to depend on interfaces they do not use. Split large interfaces into smaller, specific ones. Violation example: a Printer interface with methods print(), scan(), fax(); a simple printer that only prints is forced to implement scan() and fax() with empty bodies. Fix: separate into Printable, Scannable, Faxable interfaces.
5. Dependency Inversion Principle (D): High-level modules should not depend on low-level modules; both should depend on abstractions (interfaces). Program to interfaces, not implementations. Violation example: a service class creates its own database connection (new MySQLDatabase()). Fix: inject a Database interface via constructor injection; swap implementations for testing or migration without changing the service class.
Creational design patterns
Creational patterns:
1. Singleton: Ensures a class has only one instance and provides a global access point to it. Thread-safe Singleton (double-checked locking): ```java class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } ``` Real-world use: configuration managers, connection pools, logging. Criticism: Singletons are global state; they make code harder to test. Prefer dependency injection; inject the 'singleton' as a dependency rather than accessing it via getInstance().
2. Factory Method: Defines an interface for creating objects but lets subclasses decide which class to instantiate. Use when: the exact type of object to create is determined by a subclass or by runtime configuration. Example: a notification factory creates SMS, Email, or Push notification objects based on user preferences.
3. Abstract Factory: Provides an interface for creating families of related objects without specifying concrete classes. Use when: the system must be independent of how its objects are created, and when families of related objects must be used together. Example: UI component factories (WindowsUIFactory creates WindowsButton, WindowsTextfield; MacUIFactory creates MacButton, MacTextfield).
4. Builder: Separates the construction of a complex object from its representation. Useful when: an object requires many optional parameters (telescoping constructor problem: too many constructor overloads). ```java Person person = new Person.Builder('Rahul', 'Sharma') .age(28) .email('rahul@example.com') .phone('9876543210') .build(); ``` Real-world use: building HTTP requests, SQL queries (query builders), configuration objects.
Structural design patterns
Structural patterns:
1. Decorator: Attaches additional responsibilities to an object dynamically. Wraps an object in another object that has the same interface but adds new behaviour. Java example: Java I/O streams are a classic Decorator pattern (FileInputStream wrapped by BufferedInputStream wrapped by DataInputStream). Use when: you need to add responsibilities to individual objects without subclassing (subclassing leads to a class explosion).
2. Proxy: Provides a surrogate or placeholder for another object to control access to it. Types of proxies: Virtual Proxy (lazy initialisation; creates the real object only when needed; e.g., a proxy for an expensive database connection), Remote Proxy (represents an object in a different address space; RPC stub), Protection Proxy (controls access based on permissions), Caching Proxy (caches the results of expensive operations). Real-world use: Spring AOP (aspect-oriented programming) uses dynamic proxies to add cross-cutting concerns (logging, security, transactions) to beans without modifying the bean code.
3. Adapter: Converts the interface of a class into another interface that clients expect. Allows incompatible interfaces to work together. Real-world example: a legacy payment system uses a different API than your new payment provider; an adapter wraps the legacy system to conform to the new interface.
4. Facade: Provides a simplified interface to a complex subsystem. The facade hides the complexity and provides a single entry point for clients. Real-world example: a HomeAutomation facade provides turnOnMovie() (sets the lighting, turns on the TV, dims the lights, starts the receiver) rather than the client calling each subsystem separately. In code: a ShoppingService facade that coordinates calls to CartService, InventoryService, PaymentService, and NotificationService.
Practise design patterns and object-oriented design interview questions with HireStepX's AI voice interviewer. Get scored feedback on your explanations of SOLID principles, design patterns, and code architecture. First 2 sessions free.
Practice freeBehavioral design patterns
Behavioral patterns:
1. Observer: Defines a one-to-many dependency: when one object (Subject) changes state, all its dependents (Observers) are notified automatically. Real-world use: event systems, GUI frameworks, reactive programming (RxJava, Project Reactor). Java example: model (Subject) notifies views (Observers) when the model changes (MVC pattern).
2. Strategy: Defines a family of algorithms, encapsulates each one, and makes them interchangeable. The algorithm can be selected at runtime. Use when: you need multiple variants of an algorithm. Real-world examples: sorting strategies (merge sort, quick sort, heap sort), payment methods (CreditCard, UPI, NetBanking each implement a PaymentStrategy), compression algorithms.
3. Command: Encapsulates a request as an object, allowing you to parameterise, queue, log, and undo operations. The command object knows who the receiver is and what action to perform. Real-world use: task queues (each task is a Command object), undo/redo functionality (each action is a Command; undo calls the reverse operation), macro recording.
4. Template Method: Defines the skeleton of an algorithm in a base class and lets subclasses fill in the specific steps. The overall structure is fixed; the implementation of specific steps varies. Real-world use: framework hooks (Spring's JdbcTemplate defines the database query skeleton; you provide the SQL and RowMapper; the template handles connection management, execution, cleanup).
5. Chain of Responsibility: Passes a request along a chain of handlers. Each handler decides whether to process the request or pass it to the next handler. Real-world use: HTTP request processing pipelines (middleware chains in Express, Spring filter chains, Java servlet filters), logging frameworks (a logger passes a message through a chain of handlers that each decide whether to handle it based on log level).
Frequently asked questions
Explore more