DDD — это подход к разработке сложных программных систем, который фокусируется на моделировании предметной области (бизнес-логики) и организации кода вокруг бизнес-концепций.
Логическая граница, внутри которой определены конкретные модели и термины. Например:
Общий язык между разработчиками и бизнес-экспертами:
// Вместо
class UserOrderProcessor {
public function processTransaction() {...}
}
// Используем термины из предметной области
class OrderFulfillment {
public function completePurchase() {...}
}
Объекты с идентичностью, которые изменяются со временем:
class Product {
private ProductId $id;
private string $name;
public function rename(string $newName): void {
$this->name = $newName;
}
}
Неизменяемые объекты без идентичности:
class Money {
public function __construct(
private float $amount,
private Currency $currency
) {}
public function add(Money $other): Money {
if (!$this->currency->equals($other->currency)) {
throw new InvalidArgumentException('Currencies must match');
}
return new Money($this->amount + $other->amount, $this->currency);
}
}
Группа связанных объектов, рассматриваемая как единое целое:
class Order {
private OrderId $id;
private array $lineItems;
public function addItem(Product $product, int $quantity): void {
$this->lineItems[] = new LineItem($product, $quantity);
}
}
Интерфейсы для доступа к агрегатам:
interface OrderRepository {
public function save(Order $order): void;
public function findById(OrderId $id): ?Order;
}
Логика, которая не принадлежит конкретному объекту:
class OrderProcessingService {
public function __construct(
private OrderRepository $orders,
private InventoryService $inventory
) {}
public function process(Order $order): void {
if (!$this->inventory->isAvailable($order->items())) {
throw new DomainException('Items not available');
}
$order->markAsProcessed();
$this->orders->save($order);
}
}
Факты, произошедшие в домене:
class OrderCompleted {
public function __construct(
public readonly OrderId $orderId,
public readonly DateTimeImmutable $occurredOn
) {}
}
Пример CQRS:
class PlaceOrderHandler {
public function __construct(
private OrderRepository $orders,
private EventDispatcher $dispatcher
) {}
public function handle(PlaceOrderCommand $command): void {
$order = Order::place(
$command->orderId,
$command->products
);
$this->orders->save($order);
$this->dispatcher->dispatch(new OrderPlaced($order->id()));
}
}
Пример структуры папок:
src/
Domain/
Model/
Order/
Order.php
OrderId.php
LineItem.php
Repository/
OrderRepository.php
Service/
OrderProcessingService.php
Event/
OrderPlaced.php
Application/
Command/
PlaceOrderHandler.php
Infrastructure/
Persistence/
DoctrineOrderRepository.php
DDD — это мощный подход для сложных систем, который требует значительных усилий для правильной реализации. Он особенно полезен, когда сложность предметной области высока, а бизнес-логика подвержена частым изменениям. Ключевые преимущества — лучшее понимание домена, более поддерживаемый код и четкое разделение ответственности.