Factory Method includes one create method to create one product type.
Create multiple product types? → Abstract Factory
✅ Single Responsibility Principle (SRP)
✅ Open/Closed Principle (OCP)
✅ Liskov Substitution Principle (LSP) / Interface Segregation Principle (ISP)
✅ Dependency Inversion Principle (DIP)
// Abstract Factory
abstract class ProductCreator {
// Create method
public abstract create(): Product;
// Reusable Shared Logic
protected shippingCost = 0;
// @final
public setShippingCost(cost: number) {
this.shippingCost = cost;
}
}
// Concrete Factory
class ProductCreatorA extends ProductCreator {
public create(): Product {
// The product can either be encapsulated in the factory or use DI injection.
// - Encapsulation: for fixed type cohesion and simplicity
// - DI: for testability and runtime flexibility
return new ProductA(this.shippingCost, 100);
}
}
// Abstract Product
interface Product {
totalCost(): string;
}
// Concrete Product
class ProductA implements Product {
constructor(
private shippingCost: number,
private basePrice: number) {}
public totalCost(): void {
const totalCost = this.basePrice + this.shippingCost;
return `Total cost of the product: $${totalCost}`
}
}
// Client
function compute(productCreator: ProductCreator) {
productCreator.setShippingCost(15);
let product = productCreator.create()
product.totalCost()
}
compute(new ProductCreatorA());
Normally, the Reusable Shared Logic exists in Abstract Factory.