Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке анемічна модель домену і чому її вважають антипатерном?

Анемічна модель - об'єкти домену містять лише дані (поля, геттери, сеттери), а вся поведінка живе в окремих сервісах. Модель - це просто структура для бази.

// анемічна модель
class Order extends Model {}

class OrderService
{
    public function cancel(Order $order): void
    {
        if ($order->status === 'shipped') {
            throw new DomainException('Відправлене замовлення не скасувати');
        }
        $order->status = 'cancelled';
        $order->cancelled_at = now();
        $order->save();
    }
}

Мартін Фаулер назвав це антипатерном: об'єкти виглядають як об'єктна модель, але насправді це процедурний код - дані окремо, функції окремо.

Проблеми:

  • правила розпорошені: перевірку «чи можна скасувати» хтось повторить в іншому сервісі, контролері, команді - і забуде одну з умов;
  • будь-хто може зламати інваріанти: $order->status = 'cancelled' можна написати будь-де, оминувши правила;
  • сервіси розростаються до «божественних» класів на тисячі рядків.

Багата модель - поведінка поруч з даними:

class Order extends Model
{
    public function cancel(string $reason): void
    {
        if ($this->status === OrderStatus::Shipped) {
            throw new OrderAlreadyShipped($this);
        }

        $this->status = OrderStatus::Cancelled;
        $this->cancelled_at = now();
        $this->cancellation_reason = $reason;
    }
}

Правило скасування - в одному місці, і викликати його можна лише через метод з назвою з єдиної мови.

Чи завжди анемічна модель погана? Ні:

  • CRUD-застосунки без складної логіки - анемічна модель простіша й чесніша;
  • «тонкі» моделі + actions (окремий клас на дію: CancelOrder) - популярний у Laravel підхід. Він не багата модель у класичному сенсі, але логіка кожної операції зібрана в одному місці, і це вже краще за розмазаний код.

Критерій: якщо одні й ті самі правила повторюються в кількох місцях або бізнес-інваріанти порушуються «випадково» - логіці час переїхати ближче до даних.

Докладніше в документації: Martin Fowler: Anemic Domain Model

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання