Factory Pattern
Creates objects without specifying their concrete classes
Pattern Overview
🏗️ The Factory Pattern - Object Creation Made Simple
Creates objects without specifying the exact class to create. Perfect for when you need flexibility in object creation!
- Core Problem Solved:
- Decouple object creation from usage
- Support multiple product types
- Enable runtime object type decisions
- Centralize creation logic
- Simple Factory: Static method returns objects based on input
- Factory Method: Virtual method subclasses can override
- Abstract Factory: Create families of related objects
- Real-World Applications:
- UI component libraries (buttons, inputs, modals)
- Database connection managers
- Payment processor selection
- Plugin systems and middleware
- API client generators
- Configuration-based object creation
- Modern Usage Examples:
- React component factories
- Database ORM adapters
- Microservice client factories
- Cloud provider abstractions
Examples:
Logging system - create appropriate logger based on configuration
Input:
LoggerFactory.createLogger('console')Output:
ConsoleLogger instanceComponent library - generate UI elements based on type and props
Input:
uiFactory.createComponent('button', 'Click me')Output:
Button component instanceE-commerce - select payment provider based on user preference
Input:
PaymentProcessorFactory.createProcessor('stripe')Output:
StripeProcessor instanceDynamic UI - generate and display components programmatically
Input:
factory.createAndRender('modal', 'Alert', 'Save changes?')Output:
Rendered modal HTML stringConcepts
Object CreationClass AbstractionRuntime DecisionsCentralized LogicType Flexibility
Complexity Analysis
Time:O(1) - constant time creation
Space:O(1) - per created object
Implementation
LoggerFactory
Time: O(1) | Space: O(1)
// Simple Factory Implementation
interface Logger {
log(message: string): void;
getType(): string;
}
class ConsoleLogger implements Logger {
log(message: string): void {
console.log(`[CONSOLE] ${new Date().toISOString()}: ${message}`);
}
getType(): string {
return 'console';
}
}
class FileLogger implements Logger {
constructor(private filename: string) {}
log(message: string): void {
const logEntry = `[FILE:${this.filename}] ${new Date().toISOString()}: ${message}`;
console.log(`Writing to file: ${logEntry}`);
}
getType(): string {
return 'file';
}
}
class LoggerFactory {
public static createLogger(type: string, config?: string): Logger {
switch (type.toLowerCase()) {
case 'console':
return new ConsoleLogger();
case 'file':
return new FileLogger(config || 'app.log');
default:
throw new Error(`Unknown logger type: ${type}`);
}
}
}