Factory Method Pattern - Flexible Object Creation in TypeScript
Master the Factory Method pattern for flexible object creation. Learn how to decouple client code from concrete classes using TypeScript factory methods.
Detailed Explanation
Factory Method Pattern
The Factory Method pattern defines an interface for creating objects but lets subclasses decide which class to instantiate. It promotes loose coupling by eliminating the need for client code to know concrete class names.
Problem It Solves
When code directly instantiates objects with new ConcreteClass(), it creates tight coupling. Adding new types requires modifying existing code everywhere instances are created, violating the Open/Closed Principle.
Implementation
interface Transport {
deliver(cargo: string): string;
}
class Truck implements Transport {
deliver(cargo: string) {
return \`Delivering \${cargo} by road\`;
}
}
class Ship implements Transport {
deliver(cargo: string) {
return \`Delivering \${cargo} by sea\`;
}
}
abstract class Logistics {
abstract createTransport(): Transport;
planDelivery(cargo: string): string {
const transport = this.createTransport();
return transport.deliver(cargo);
}
}
class RoadLogistics extends Logistics {
createTransport() { return new Truck(); }
}
class SeaLogistics extends Logistics {
createTransport() { return new Ship(); }
}
Relationship to Other Patterns
Factory Method is closely related to Abstract Factory (which uses factory methods to create families of objects) and Template Method (the factory method is essentially a template method for object creation). It is often combined with Prototype when the factory clones objects rather than creating them from scratch.
Best Practices
Use Factory Method when you expect new product types to be added in the future. If you only have one or two product types and no plans for extension, a simple conditional or parameterized factory function may suffice.
Use Case
Factory Method is widely used in UI frameworks where different platforms (web, mobile, desktop) need different widget implementations, in plugin architectures that load modules dynamically, and in notification systems that send via email, SMS, or push depending on configuration.