Discover how to build flexible systems that adapt easily to new requirements without rewriting your code!
Why Abstract Factory pattern in LLD? - Purpose & Use Cases
Imagine you are building a software system that needs to create families of related objects, like different types of user interfaces for various platforms (Windows, Mac, Linux). You try to create each object manually by writing separate code for each platform and each UI component.
This manual approach quickly becomes messy and hard to maintain. Every time you add a new platform or UI component, you must change many parts of your code. It is easy to make mistakes, and the code becomes tightly coupled and hard to extend.
The Abstract Factory pattern provides a clean way to create families of related objects without specifying their concrete classes. It defines interfaces for creating objects, letting you swap entire families easily and keep your code flexible and organized.
if platform == 'Windows': button = WindowsButton() elif platform == 'Mac': button = MacButton()
factory = getFactory(platform) button = factory.createButton()
This pattern enables building scalable and maintainable systems that can support multiple product families without changing existing code.
Think of a car factory that can produce different models (SUV, Sedan) with different parts (engine, tires) depending on the country's regulations. The Abstract Factory lets the factory switch production lines easily without redesigning the whole process.
Manual creation of related objects leads to complex, error-prone code.
Abstract Factory provides interfaces to create object families cleanly.
It improves flexibility, scalability, and maintainability of software.
Practice
Abstract Factory pattern in system design?Solution
Step 1: Understand the role of Abstract Factory
The Abstract Factory pattern is designed to create related objects without exposing their concrete classes.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.Final Answer:
To create families of related objects without specifying their concrete classes -> Option AQuick Check:
Abstract Factory = Create related objects [OK]
- Confusing Abstract Factory with Singleton pattern
- Thinking it creates only one object
- Mixing it up with Builder or Factory Method
Solution
Step 1: Identify correct interface syntax
Abstract Factory is usually declared as an interface with methods to create related products.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.Final Answer:
interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; } -> Option DQuick Check:
Abstract Factory interface = interface AbstractFactory { createProductA(): ProductA; createProductB(): ProductB; } [OK]
- Using concrete class instead of interface
- Returning product instances directly in constructor
- Confusing factory function with abstract factory interface
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());Solution
Step 1: Identify which factory is used
The client function is called withnew VictorianFactory(), so VictorianFactory methods will be used.Step 2: Trace method calls and outputs
VictorianFactory'screateChair()returns 'Victorian Chair' andcreateSofa()returns 'Victorian Sofa'. These are printed.Final Answer:
Victorian Chair Victorian Sofa -> Option AQuick Check:
VictorianFactory output = Victorian Chair\nVictorian Sofa [OK]
- Assuming ModernFactory is used instead
- Confusing method names or return values
- Expecting errors due to missing interface
class Factory {
createProduct() {
return new Product();
}
}
class Product {}
const factory = new Factory();
const product = factory.createProduct();
console.log(product.name.toUpperCase());Solution
Step 1: Analyze the Product class and usage
The Product class is empty and does not define a 'name' property.Step 2: Understand the console.log statement
Accessingproduct.namereturnsundefined, and callingtoUpperCase()on it causes a TypeError runtime error.Final Answer:
Product class does not have a 'name' property, causing undefined access -> Option BQuick Check:
Accessing missing property = Product class does not have a 'name' property, causing undefined access [OK]
- Thinking Factory cannot instantiate Product
- Expecting interface is mandatory at runtime
- Assuming createProduct returns null or undefined
Solution
Step 1: Understand the need for consistency
Abstract Factory helps create families of related objects that match a theme or style.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.Final Answer:
Create separate factories for Light and Dark themes, each producing themed Buttons and Checkboxes -> Option CQuick Check:
Theme consistency = Separate factories [OK]
- Mixing themes in one factory
- Creating components directly in client code
- Partial factory implementations missing products
Ready to prove it?
Pass the test and this pattern moves unknown
