Bird
Raised Fist0
LLDsystem_design~25 mins

Abstract Factory pattern in LLD - System Design Exercise

Choose your learning style10 modes available
Design: Abstract Factory Pattern Implementation
Design and implement the Abstract Factory pattern focusing on the creation of related product families. Out of scope are specific product implementations beyond demonstration and integration with external systems.
Functional Requirements
FR1: Create families of related or dependent objects without specifying their concrete classes.
FR2: Support multiple product variants that can be used interchangeably.
FR3: Allow easy addition of new product families without changing existing code.
FR4: Ensure that client code is decoupled from the concrete implementations of products.
Non-Functional Requirements
NFR1: Design should promote scalability and maintainability.
NFR2: Factory creation should be efficient with minimal runtime overhead.
NFR3: The system should support at least two distinct product families.
NFR4: The design must follow object-oriented principles and best practices.
Think Before You Design
Questions to Ask
❓ Question 1
❓ Question 2
❓ Question 3
❓ Question 4
Key Components
Abstract Factory interface defining creation methods
Concrete Factory classes implementing the abstract factory
Abstract Product interfaces for each product type
Concrete Product classes implementing the product interfaces
Client code that uses the abstract factory and products
Design Patterns
Factory Method pattern for creating individual products
Dependency Injection to provide factories to clients
Singleton pattern if only one instance of a factory is needed
Interface Segregation to keep product interfaces focused
Reference Architecture
Client
  |
  v
AbstractFactory <---- ConcreteFactory1
  |                      |
  |                      v
  |                 ProductFamily1
  |
  v
ConcreteFactory2
  |
  v
ProductFamily2
Components
AbstractFactory
Interface or Abstract Class
Defines methods to create abstract products.
ConcreteFactory1
Class implementing AbstractFactory
Creates products of the first product family.
ConcreteFactory2
Class implementing AbstractFactory
Creates products of the second product family.
AbstractProductA
Interface or Abstract Class
Defines interface for product type A.
AbstractProductB
Interface or Abstract Class
Defines interface for product type B.
ConcreteProductA1
Class implementing AbstractProductA
Concrete product A of family 1.
ConcreteProductB1
Class implementing AbstractProductB
Concrete product B of family 1.
ConcreteProductA2
Class implementing AbstractProductA
Concrete product A of family 2.
ConcreteProductB2
Class implementing AbstractProductB
Concrete product B of family 2.
Client
Class
Uses AbstractFactory and products without knowing concrete classes.
Request Flow
1. Client requests a factory instance (ConcreteFactory1 or ConcreteFactory2).
2. Client calls factory methods to create abstract products (ProductA, ProductB).
3. Factory returns concrete product instances corresponding to its family.
4. Client uses products through their abstract interfaces.
5. Client can switch factories to use different product families without code changes.
Database Schema
Not applicable for Abstract Factory pattern as it is a design pattern focused on object creation and does not involve persistent storage.
Scaling Discussion
Bottlenecks
Adding new product families requires creating new concrete factories and products.
Client code may become complex if many product types are involved.
Overhead of maintaining multiple interfaces and classes.
Solutions
Use inheritance and interface segregation to keep code modular and manageable.
Apply Dependency Injection to manage factory instances dynamically.
Automate factory and product registration to reduce manual coding.
Limit product types per factory to reduce complexity.
Interview Tips
Time: Spend 10 minutes explaining the problem and requirements, 20 minutes designing the pattern with diagrams and code examples, and 15 minutes discussing scalability and trade-offs.
Explain the problem of creating related objects without specifying concrete classes.
Describe how Abstract Factory decouples client from concrete implementations.
Show how adding new product families is easy and does not affect client code.
Discuss trade-offs like increased number of classes and interfaces.
Mention related patterns like Factory Method and Dependency Injection.

Practice

(1/5)
1. What is the main purpose of the Abstract Factory pattern in system design?
easy
A. To create families of related objects without specifying their concrete classes
B. To allow direct instantiation of concrete classes
C. To enforce a single instance of a class
D. To simplify database queries

Solution

  1. Step 1: Understand the role of Abstract Factory

    The Abstract Factory pattern is designed to create related objects without exposing their concrete classes.
  2. Step 2: Compare options with the pattern's purpose

    To create families of related objects without specifying their concrete classes correctly describes this purpose, while others describe different patterns or unrelated concepts.
  3. Final Answer:

    To create families of related objects without specifying their concrete classes -> Option A
  4. Quick Check:

    Abstract Factory = Create related objects [OK]
Hint: Abstract Factory creates related objects without concrete classes [OK]
Common Mistakes:
  • Confusing Abstract Factory with Singleton pattern
  • Thinking it creates only one object
  • Mixing it up with Builder or Factory Method
2. Which of the following is the correct way to declare an Abstract Factory interface in a typical object-oriented design?
easy
A. var AbstractFactory = { create: function() { return ProductA; } }
B. class AbstractFactory { new ProductA(); new ProductB(); }
C. function AbstractFactory() { return new ProductA(); }
D. interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; }

Solution

  1. Step 1: Identify correct interface syntax

    Abstract Factory is usually declared as an interface with methods to create related products.
  2. Step 2: Analyze each option

    interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; } correctly declares an interface with creation methods. Options A, B, and C do not follow interface or abstract factory conventions.
  3. Final Answer:

    interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; } -> Option D
  4. Quick Check:

    Abstract Factory interface = interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; } [OK]
Hint: Abstract Factory uses interface with creation methods [OK]
Common Mistakes:
  • Using concrete class instead of interface
  • Returning product instances directly in constructor
  • Confusing factory function with abstract factory interface
3. Given the following code snippet using Abstract Factory pattern, what will be the output?
class ModernFactory {
  createChair() { return 'Modern Chair'; }
  createSofa() { return 'Modern Sofa'; }
}
class VictorianFactory {
  createChair() { return 'Victorian Chair'; }
  createSofa() { return 'Victorian Sofa'; }
}
function client(factory) {
  console.log(factory.createChair());
  console.log(factory.createSofa());
}
client(new VictorianFactory());
medium
A. Victorian Chair\nVictorian Sofa
B. Modern Chair\nModern Sofa
C. Error: factory methods not found
D. undefined\nundefined

Solution

  1. Step 1: Identify which factory is used

    The client function is called with new VictorianFactory(), so VictorianFactory methods will be used.
  2. Step 2: Trace method calls and outputs

    VictorianFactory's createChair() returns 'Victorian Chair' and createSofa() returns 'Victorian Sofa'. These are printed.
  3. Final Answer:

    Victorian Chair Victorian Sofa -> Option A
  4. Quick Check:

    VictorianFactory output = Victorian Chair\nVictorian Sofa [OK]
Hint: Check which factory instance is passed to client [OK]
Common Mistakes:
  • Assuming ModernFactory is used instead
  • Confusing method names or return values
  • Expecting errors due to missing interface
4. In the following Abstract Factory implementation, what is the main issue causing a runtime error?
class Factory {
  createProduct() {
    return new Product();
  }
}
class Product {}
const factory = new Factory();
const product = factory.createProduct();
console.log(product.name.toUpperCase());
medium
A. Missing interface declaration for Factory
B. Product class does not have a 'name' property, causing undefined access
C. Factory class cannot instantiate Product directly
D. createProduct method is not returning an object

Solution

  1. Step 1: Analyze the Product class and usage

    The Product class is empty and does not define a 'name' property.
  2. Step 2: Understand the console.log statement

    Accessing product.name returns undefined, and calling toUpperCase() on it causes a TypeError runtime error.
  3. Final Answer:

    Product class does not have a 'name' property, causing undefined access -> Option B
  4. Quick Check:

    Accessing missing property = Product class does not have a 'name' property, causing undefined access [OK]
Hint: Check if accessed properties exist on created objects [OK]
Common Mistakes:
  • Thinking Factory cannot instantiate Product
  • Expecting interface is mandatory at runtime
  • Assuming createProduct returns null or undefined
5. You are designing a UI toolkit that supports multiple themes (Light and Dark). Using the Abstract Factory pattern, which design ensures that all UI components (Button, Checkbox) are consistent with the selected theme?
hard
A. Create Buttons and Checkboxes directly in client code based on theme
B. Use a single factory that creates default Buttons and Checkboxes ignoring theme
C. Create separate factories for Light and Dark themes, each producing themed Buttons and Checkboxes
D. Use a factory that creates only Buttons and let client create Checkboxes

Solution

  1. Step 1: Understand the need for consistency

    Abstract Factory helps create families of related objects that match a theme or style.
  2. Step 2: Evaluate design options

    Create separate factories for Light and Dark themes, each producing themed Buttons and Checkboxes creates separate factories for each theme, ensuring all components are consistent. Other options break consistency or delegate creation improperly.
  3. Final Answer:

    Create separate factories for Light and Dark themes, each producing themed Buttons and Checkboxes -> Option C
  4. Quick Check:

    Theme consistency = Separate factories [OK]
Hint: Use one factory per theme to keep components consistent [OK]
Common Mistakes:
  • Mixing themes in one factory
  • Creating components directly in client code
  • Partial factory implementations missing products
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard