Title: Design Patterns — LearnCoachAssist

Q: What are Design Patterns in software engineering?
A: Design patterns are reusable solutions to commonly occurring problems in software design. They were popularized by the Gang of Four (GoF) in their 1994 book. They are not code, but templates for solving problems that can be adapted to many situations.
Benefits:
- Provide a shared vocabulary among developers
- Promote proven, tested solutions
- Improve code maintainability and flexibility

Q: What are the three categories of GoF Design Patterns?
A: The three categories are:
- Creational Patterns – Deal with object creation mechanisms (e.g., Singleton, Factory Method, Builder)
- Structural Patterns – Deal with object composition and relationships (e.g., Adapter, Decorator, Facade)
- Behavioral Patterns – Deal with communication between objects (e.g., Observer, Strategy, Command)

Q: What is the Singleton pattern?
A: The Singleton pattern ensures a class has only one instance and provides a global point of access to it.
Key traits:
- Private constructor
- Static method to get the instance
- Lazy or eager initialization
Example: public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; }

Q: What are the drawbacks of the Singleton pattern?
A: Singleton drawbacks include:
- Introduces global state, making code harder to test
- Violates the Single Responsibility Principle (manages its own lifecycle)
- Thread safety issues if not implemented carefully
- Tight coupling to the Singleton class
- Often considered an anti-pattern when overused

Q: What is the Factory Method pattern?
A: The Factory Method defines an interface for creating objects but lets subclasses decide which class to instantiate.
abstract class Creator {
  abstract Product factoryMethod();
}
Benefits:
- Follows the Open/Closed Principle
- Decouples client code from concrete classes
- Subclasses control instantiation

Q: What is the Abstract Factory pattern?
A: The Abstract Factory provides an interface for creating families of related objects without specifying their concrete classes.
Example: A UI toolkit factory that creates buttons, checkboxes, and menus for different OS platforms.
interface GUIFactory {
  Button createButton();
  Checkbox createCheckbox();
}
Use when the system must be independent of how its products are created.

Q: How does Abstract Factory differ from Factory Method?
A: - Factory Method uses inheritance — a single method in a subclass creates one product
- Abstract Factory uses composition — a factory object creates a family of related products
- Factory Method creates one product; Abstract Factory creates multiple related products
- Abstract Factory often uses Factory Methods internally

Q: What is the Builder pattern?
A: The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations.
Pizza pizza = new Pizza.Builder()
  .size("large")
  .cheese(true)
  .pepperoni(true)
  .build();
Use when:
- An object has many optional parameters
- Construction involves multiple steps

Q: What is the Prototype pattern?
A: The Prototype pattern creates new objects by cloning an existing object (the prototype) rather than using constructors.
Prototype clone = original.clone();
Benefits:
- Avoids costly creation from scratch
- Hides the complexities of creating new instances
- Useful when objects differ only slightly
Uses the Cloneable interface in Java or copy constructors in C++.

Q: What is the Adapter pattern?
A: The Adapter pattern converts the interface of a class into another interface that clients expect. It lets classes work together that couldn't otherwise due to incompatible interfaces.
Analogy: A power plug adapter lets a US plug fit a European socket.
Two forms:
- Class Adapter – uses multiple inheritance
- Object Adapter – uses composition (preferred)

Q: What is the Bridge pattern?
A: The Bridge pattern decouples an abstraction from its implementation so the two can vary independently.
Example: Shape (abstraction) and Color (implementation) — a RedCircle combines both without creating a class for every combination.
Key benefit: Prevents a cartesian product explosion of subclasses when you have multiple dimensions of variation.

Q: What is the Composite pattern?
A: The Composite pattern composes objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions uniformly.
Example: A file system where both File and Directory implement a common FileSystemComponent interface.
interface Component {
  void operation();
}
class Leaf implements Component {...}
class Composite implements Component {...}

Q: What is the Decorator pattern?
A: The Decorator pattern attaches additional responsibilities to an object dynamically. It provides a flexible alternative to subclassing for extending functionality.
Example: new BufferedInputStream(new FileInputStream("file.txt")) in Java I/O.
Key traits:
- Wraps the original object
- Implements the same interface
- Adds behavior before/after delegating to the wrapped object

Q: What is the Facade pattern?
A: The Facade pattern provides a simplified interface to a complex subsystem. It doesn't add new functionality — it makes existing functionality easier to use.
Example: A HomeTheaterFacade with a watchMovie() method that internally turns on the projector, dims lights, and starts the player.
Benefits:
- Reduces coupling between client and subsystem
- Simplifies usage for common tasks

Q: What is the Flyweight pattern?
A: The Flyweight pattern reduces memory usage by sharing common state (intrinsic state) among many objects, while keeping unique state (extrinsic state) external.
Example: In a text editor, each character object shares font data (intrinsic) but has unique position data (extrinsic).
Use when:
- You have a large number of similar objects
- Most object state can be made extrinsic
- Memory optimization is critical

Q: What is the Proxy pattern?
A: The Proxy pattern provides a surrogate or placeholder for another object to control access to it.
Types of proxies:
- Virtual Proxy – delays creation of expensive objects (lazy loading)
- Protection Proxy – controls access based on permissions
- Remote Proxy – represents an object in a different address space
- Caching Proxy – stores results of expensive operations

Q: How do Decorator and Proxy differ?
A: - Decorator adds new behavior/responsibilities to an object
- Proxy controls access to an object without adding new behavior
- Decorator is chosen by the client; Proxy is typically transparent to the client
- Both wrap an object and implement the same interface, but their intent differs

Q: What is the Observer pattern?
A: The Observer pattern defines a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified automatically.
subject.addObserver(observer);
subject.notifyAll();
Examples:
- Event listeners in GUIs
- Pub/sub messaging systems
- Reactive programming (RxJS, LiveData)

Q: What is the Strategy pattern?
A: The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from the clients that use it.
context.setStrategy(new QuickSortStrategy());
context.executeStrategy(data);
Benefits:
- Eliminates conditional statements for algorithm selection
- Easy to add new strategies without modifying existing code

Q: What is the Command pattern?
A: The Command pattern encapsulates a request as an object, letting you parameterize clients with different requests, queue or log requests, and support undo operations.
interface Command {
  void execute();
  void undo();
}
Use cases:
- Undo/Redo functionality
- Macro recording
- Task queues and scheduling
- Transaction-based systems

Q: What is the State pattern?
A: The State pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
Example: A TCPConnection that behaves differently when in Established, Listening, or Closed states.
Key benefit: Replaces complex if/else or switch statements with polymorphism. Each state is a separate class implementing a common interface.

Q: How do State and Strategy patterns differ?
A: - Strategy: Client chooses which algorithm to use; strategies are typically stateless
- State: The object transitions between states internally; states often know about each other
- Both use composition and polymorphism, but intent differs
- Strategy = "how to do something"; State = "what to do based on current condition"

Q: What is the Template Method pattern?
A: The Template Method defines the skeleton of an algorithm in a base class, deferring some steps to subclasses. Subclasses override specific steps without changing the algorithm's structure.
abstract class DataParser {
  final void parse() {
    openFile();
    readData(); // abstract
    closeFile();
  }
}
Uses the Hollywood Principle: "Don't call us, we'll call you."

Q: What is the Iterator pattern?
A: The Iterator pattern provides a way to access elements of a collection sequentially without exposing its underlying representation.
Iterator<Item> it = collection.iterator();
while (it.hasNext()) {
  Item item = it.next();
}
Benefits:
- Uniform traversal interface for different collections
- Supports multiple simultaneous traversals
- Hides internal data structure complexity

Q: What is the Mediator pattern?
A: The Mediator pattern defines an object that encapsulates how a set of objects interact. It promotes loose coupling by preventing objects from referring to each other directly.
Example: An air traffic control tower mediates communication between aircraft — planes don't talk to each other directly.
Benefits:
- Reduces many-to-many relationships to one-to-many
- Centralizes complex communication logic

Q: What is the Chain of Responsibility pattern?
A: The Chain of Responsibility passes a request along a chain of handlers. Each handler decides either to process the request or pass it to the next handler in the chain.
Example: Middleware in web frameworks like Express.js or Laravel.
handler1.setNext(handler2);
handler2.setNext(handler3);
handler1.handle(request);
Benefits:
- Decouples sender from receiver
- Dynamically compose processing chains

Q: What is the Visitor pattern?
A: The Visitor pattern lets you add new operations to existing object structures without modifying the classes of the elements.
Uses double dispatch: the element accepts a visitor, then calls the visitor's method for its type.
element.accept(visitor);
// inside: visitor.visit(this);
Trade-off: Easy to add new operations, but hard to add new element types (requires updating all visitors).

Q: What is the Memento pattern?
A: The Memento pattern captures and externalizes an object's internal state so it can be restored later, without violating encapsulation.
Three roles:
- Originator – the object whose state is saved
- Memento – stores the snapshot of state
- Caretaker – manages mementos (e.g., undo stack)
Use cases: Undo functionality, checkpoints in games, transaction rollback.

Q: What is the Single Responsibility Principle (SRP)?
A: SRP states: A class should have only one reason to change, meaning it should have only one job or responsibility.
Example violation: A User class that handles authentication, database persistence, and email sending.
Fix: Split into UserAuthenticator, UserRepository, and EmailService.
Benefits:
- Easier to understand and maintain
- Reduced coupling
- Easier testing

Q: What is the Open/Closed Principle (OCP)?
A: OCP states: Software entities should be open for extension but closed for modification.
Instead of modifying existing code to add new behavior, extend it through inheritance, composition, or interfaces.
Example: Use a Strategy pattern so new algorithms can be added without changing the context class.
Violation: Adding if/else branches every time a new type is introduced.

Q: What is the Liskov Substitution Principle (LSP)?
A: LSP states: Objects of a superclass should be replaceable with objects of a subclass without altering the correctness of the program.
Classic violation: Square extends Rectangle — setting width on a Square unexpectedly changes height.
Rules:
- Subtypes must honor the supertype's contract
- Preconditions can't be strengthened
- Postconditions can't be weakened
- Invariants must be preserved

Q: What is the Interface Segregation Principle (ISP)?
A: ISP states: Clients should not be forced to depend on interfaces they do not use. Prefer many small, specific interfaces over one large general-purpose interface.
Violation: interface Worker { void work(); void eat(); } — a Robot doesn't eat.
Fix:
interface Workable { void work(); }
interface Feedable { void eat(); }
Benefits: Reduces unnecessary dependencies and improves decoupling.

Q: What is the Dependency Inversion Principle (DIP)?
A: DIP states:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
Example: Instead of OrderService → MySQLDatabase, use OrderService → DatabaseInterface ← MySQLDatabase.
This is the foundation of Dependency Injection (DI) frameworks like Spring and Laravel's service container.

Q: How do DIP and Dependency Injection relate?
A: - DIP is a principle — depend on abstractions, not concretions
- Dependency Injection (DI) is a technique to achieve DIP — dependencies are provided (injected) from outside rather than created internally
- DI types: Constructor injection, Setter injection, Interface injection
- DI containers (Spring, Laravel, .NET) automate the wiring of dependencies

Q: What does SOLID stand for and why is it important?
A: SOLID is an acronym for five OOP design principles:
- S – Single Responsibility Principle
- O – Open/Closed Principle
- L – Liskov Substitution Principle
- I – Interface Segregation Principle
- D – Dependency Inversion Principle
Importance: They guide developers in building systems that are maintainable, flexible, testable, and resistant to code rot over time.

Q: When should you use the Singleton pattern?
A: Use Singleton when:
- Exactly one instance of a class is needed (e.g., configuration manager, connection pool, logger)
- Controlled access to a shared resource is required
Avoid when:
- You need testability (use DI instead)
- Multiple instances may be needed later
- It's used just for convenience (global state smell)
Modern alternative: Use a DI container to manage single-instance lifecycle.

Q: When should you use the Factory Method pattern?
A: Use Factory Method when:
- A class can't anticipate the class of objects it must create
- A class wants its subclasses to specify the objects it creates
- You want to localize the knowledge of which class gets created
Example: A logistics app where RoadLogistics creates Truck and SeaLogistics creates Ship, both implementing Transport.

Q: When should you use the Observer pattern?
A: Use Observer when:
- Changes in one object require updating others, and you don't know how many
- An object should notify other objects without being tightly coupled to them
- You need an event-driven architecture
Examples:
- GUI event handling
- Model-View updates in MVC
- Message brokers and pub/sub systems

Q: When should you use the Strategy pattern?
A: Use Strategy when:
- You have multiple algorithms for a specific task and want to switch between them
- You want to avoid conditional statements for selecting behavior
- You need to isolate algorithm logic from the code that uses it
Examples:
- Sorting algorithms (quick sort, merge sort)
- Payment processing (credit card, PayPal, crypto)
- Compression strategies (zip, gzip, bzip2)

Q: When should you use the Decorator pattern?
A: Use Decorator when:
- You need to add responsibilities to objects dynamically without affecting other objects
- Subclassing would result in an explosion of classes
- You want to combine behaviors flexibly at runtime
Examples:
- Java I/O streams: BufferedReader(InputStreamReader(FileInputStream))
- Middleware stacking in web frameworks
- Adding logging, caching, or auth to services

Q: What is the difference between Adapter and Facade?
A: - Adapter makes an existing interface compatible with another expected interface — wraps one class
- Facade provides a simplified interface to a complex subsystem — wraps multiple classes
- Adapter changes an interface; Facade simplifies one
- Adapter is used for interoperability; Facade is used for convenience

Q: What are anti-patterns in software design?
A: Anti-patterns are common solutions that appear beneficial but are actually counterproductive.
Common anti-patterns:
- God Object – one class that does everything
- Spaghetti Code – tangled, unstructured logic
- Golden Hammer – using one solution for every problem
- Lava Flow – dead code nobody dares to remove
- Copy-Paste Programming – duplicating instead of abstracting
Recognizing anti-patterns helps you refactor toward proper patterns.

Q: What is the God Object anti-pattern and how do you fix it?
A: The God Object (or God Class) is a class that knows too much or does too much. It violates SRP by handling multiple unrelated responsibilities.
Signs:
- Thousands of lines of code
- Dozens of methods spanning different concerns
- Many dependencies
Fix:
- Apply SRP — extract responsibilities into separate classes
- Use Facade if a simplified entry point is still needed
- Refactor incrementally using tests as a safety net

Q: What is Composition over Inheritance?
A: Composition over Inheritance is a design principle favoring composing objects (has-a) over inheriting behavior (is-a).
Why prefer composition:
- Avoids tight coupling to parent classes
- More flexible — behaviors can be changed at runtime
- Prevents deep, fragile inheritance hierarchies
- Easier to test with mock objects
Patterns that use composition: Strategy, Decorator, Observer, Bridge.

Q: What is the Hollywood Principle?
A: The Hollywood Principle states: "Don't call us, we'll call you."
High-level components control the flow and call low-level components — not the other way around.
Related patterns:
- Template Method – base class calls subclass hooks
- Observer – subject calls observers
- Dependency Injection – framework calls your code
This principle supports the Dependency Inversion Principle and Inversion of Control (IoC).

Q: What is Inversion of Control (IoC)?
A: Inversion of Control is a design principle where the control flow is inverted — instead of your code calling the framework, the framework calls your code.
Implementations:
- Dependency Injection – dependencies are provided externally
- Template Method – framework defines the skeleton, you fill in steps
- Event-driven systems – framework dispatches events to your handlers
IoC containers: Spring (Java), Laravel (PHP), .NET DI.

Q: When should you use the Builder pattern?
A: Use Builder when:
- An object requires many constructor parameters (telescoping constructor problem)
- You want to create different representations of the same type
- Construction steps need to be executed in a specific order
Examples:
- Building complex SQL queries
- Constructing UI layouts programmatically
- Creating test fixtures with many optional fields
Alternative: Named parameters in languages that support them (Python, Kotlin).

Q: When should you use the Command pattern?
A: Use Command when:
- You need undo/redo functionality
- You want to queue, log, or schedule operations
- You need to parameterize objects with operations
- You want to support macro recording (composite commands)
Examples:
- Text editor undo stack
- Database transaction rollback
- Remote control buttons mapped to device operations
- Job queues in background processing systems

Q: What is the difference between Bridge and Adapter?
A: - Adapter is applied after the system is designed — it makes incompatible interfaces work together
- Bridge is applied upfront during design — it separates abstraction from implementation to allow independent variation
- Adapter wraps an existing class; Bridge structures new code
- Adapter = retrofit; Bridge = planned decoupling

Q: What is the difference between Composite and Decorator?
A: - Composite organizes objects into tree structures (part-whole hierarchy) — treats leaf and composite uniformly
- Decorator adds responsibilities to an individual object dynamically — wraps a single object
- Composite focuses on structure; Decorator focuses on adding behavior
- Both use recursive composition, but for different purposes

Q: How do you choose the right design pattern?
A: Guidelines for choosing patterns:
- Identify what varies in your design and encapsulate it
- Match the problem to a pattern's intent, not its structure
- Don't force patterns — apply them when they solve a real problem
- Consider SOLID principles as a guide to which pattern fits
- Start simple; refactor toward patterns when complexity grows
Remember: Patterns are tools, not goals. Over-engineering with patterns is itself an anti-pattern (Pattern-itis).