Ответ
Да, "Domain-Driven Design: Tackling Complexity in the Heart of Software" Эрика Эванса — это классика, которая сильно повлияла на мой подход к проектированию сложных бизнес-систем. Ключевая ценность книги — введение единого языка (Ubiquitous Language) между разработчиками и экспертами предметной области и тактические паттерны для его отражения в коде.
В PHP-проектах я применяю такие паттерны DDD, как:
- Value Objects для представления неделимых, неизменяемых концепций (Email, Money).
- Aggregates для инкапсуляции инвариантов и управления целостностью группы связанных сущностей.
// Пример Value Object и Aggregate Root
final class Email implements Stringable {
private function __construct(private string $value) {}
public static function fromString(string $value): self {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
return new self($value);
}
public function __toString(): string { return $this->value; }
}
class Order // Aggregate Root
{
private array $lineItems = [];
private OrderStatus $status;
public function addLineItem(ProductId $productId, Quantity $qty, Price $price): void {
// Инвариант: нельзя добавлять товары в завершенный заказ
if ($this->status->isFinal()) {
throw new OrderAlreadyFinalizedException();
}
$this->lineItems[] = new LineItem($productId, $qty, $price);
}
}
Книга Эванса задает стратегический каркас, а для практической реализации в PHP я также рекомендую книги Вона Вернона и примеры из фреймворков, таких как Broadway (для CQRS/Event Sourcing).
Ответ 18+ 🔞
А, "Domain-Driven Design" Эрика Эванса! Ну это, ёпта, прям фундамент, на котором мозги у многих встали с правильной стороны. Книга-то, конечно, не для слабаков — читаешь и чувствуешь, как из ушей пар идёт, но оно того стоит, честно.
Вот в чём её главный фокус, который многих накрывает, как медный таз: она заставляет тебя говорить с бизнесменами и экспертами на одном языке. Не на этом своём программистском жаргоне, где всё "модели", "сервисы" и "репозитории", а на нормальном человеческом, который в бизнесе используют. Это и есть тот самый "единый язык" (Ubiquitous Language). И потом ты этот язык прямо в код пишешь, чтобы он не был оторван от реальности, как хуй с горы. Без этого получается пиздопроебибна: ты одно имел в виду, заказчик — другое, а в итоге система работает, но не так, и всем пиздец.
В PHP-то как это выглядит? Ну, например, эти ваши Value Objects. Это же просто песня! Вместо того чтобы таскать строку $email по всему коду и в каждом методе проверять, а валидная ли она, ты создаёшь объект Email. Один раз проверяешь при создании — и всё, потом можешь спать спокойно. Он неизменяемый, сам себя контролирует. Красота!
// Вот смотри, как это просто и элегантно
final class Email implements Stringable {
private function __construct(private string $value) {}
public static function fromString(string $value): self {
// Один раз, при рождении, проверяем — и забываем
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Ну и что это за хуйню ты мне подсунул? Это не email!');
}
return new self($value);
}
public function __toString(): string { return $this->value; }
}
А ещё есть Aggregates (Агрегаты). Вот это, блядь, мощнейшая штука для контроля над своим куском данных. Представь себе заказ (Order) в интернет-магазине. В нём есть сам заказ, список товаров, статус... Так вот, Агрегат — это такой главный по тарелке, который следит, чтобы внутри его группы всё было по правилам. Нельзя просто так взять и изменить товар в завершённом заказе. Агрегат тебе не даст, он инварианты проверяет.
class Order // Вот он, корень агрегата (Aggregate Root), главный
{
private array $lineItems = [];
private OrderStatus $status;
public function addLineItem(ProductId $productId, Quantity $qty, Price $price): void {
// А вот и инвариант: в завершённый заказ хуй что добавишь!
if ($this->status->isFinal()) {
throw new OrderAlreadyFinalizedException('Ты чё, охренел? Заказ уже закрыт!');
}
$this->lineItems[] = new LineItem($productId, $qty, $price);
}
}
Эванс, конечно, гений, он стратегию построил. Но чтобы не бздеть при реализации, особенно в PHP, надо и других авторов почитать. Вон Вернон, например, хорошо так тактические паттерны разжёвывает. И смотреть на готовые примеры из фреймворков вроде Broadway — там прямо живые примеры, как это CQRS да Event Sourcing в дело воплощать. Без этого можно в теории утонуть, ебать мои старые костыли.