Design Patterns
The Strategy Pattern: Encapsulating Algorithms
Define a family of algorithms, encapsulate each one, and make them interchangeable — open for extension, closed for modification.
The Strategy pattern defines a set of interchangeable algorithms behind a common interface. The context class delegates the algorithm to a strategy object rather than hard-coding it. This eliminates conditional branching inside the context and makes it easy to add new algorithms without modifying existing code — satisfying the Open/Closed Principle.
interface ShippingStrategy
{
public function calculate(Order $order): Money;
}
class StandardShipping implements ShippingStrategy { /* ... */ }
class ExpressShipping implements ShippingStrategy { /* ... */ }
class OrderPricer
{
public function __construct(private readonly ShippingStrategy $shipping) {}
public function total(Order $order): Money
{
return $order->subtotal()->add($this->shipping->calculate($order));
}
}Continue reading
- →
Dependency Injection and IoC Containers
Invert control of dependency creation to keep classes decoupled from their collaborators and trivially testable.
- →
The Observer Pattern and Event-Driven Design
Decouple publishers from subscribers by letting objects register interest in events without the producer knowing who is listening.
- →
The Factory Pattern: Centralising Object Creation
Delegate the responsibility of creating complex objects to a dedicated factory, keeping construction logic out of the domain and callers.