Design Patterns
Dependency Injection and IoC Containers
Invert control of dependency creation to keep classes decoupled from their collaborators and trivially testable.
Dependency Injection means that a class receives its collaborators from the outside rather than creating them itself. Constructor injection is the clearest form: the dependencies are declared as constructor parameters and provided at instantiation. This inverts control — the class no longer owns its dependencies' lifecycle — and makes substitution (for testing or configuration) straightforward without any mocking framework.
class OrderService
{
public function __construct(
private readonly OrderRepository $orders,
private readonly EventBus $events,
private readonly Clock $clock,
) {}
}
// In a test — plain PHP, no container:
$service = new OrderService(
new InMemoryOrderRepository(),
new RecordingEventBus(),
new FixedClock('2026-03-06'),
);Continue reading
- →
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 Strategy Pattern: Encapsulating Algorithms
Define a family of algorithms, encapsulate each one, and make them interchangeable — open for extension, closed for modification.
- →
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.