Design Patterns
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.
When constructing an object requires complex logic — choosing a concrete subclass, validating invariants, or coordinating multiple collaborators — that logic should not live in the caller or in the object itself. A Factory centralises creation, enforces invariants at construction time, and returns a fully initialised object. In DDD, factories are especially useful for creating aggregates whose initial state is non-trivial.
final class Order
{
private function __construct(
private readonly OrderId $id,
private readonly CustomerId $customerId,
private array $items = [],
) {}
public static function place(CustomerId $customerId, array $items): self
{
if (empty($items)) {
throw new \DomainException('An order must have at least one item.');
}
return new self(OrderId::generate(), $customerId, $items);
}
}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 Strategy Pattern: Encapsulating Algorithms
Define a family of algorithms, encapsulate each one, and make them interchangeable — open for extension, closed for modification.