Наскільки складним може бути конструктор?

← Наскільки складним може бути конструктор?

Ashterix

docs: English JsonRpcBundle docs, REST and MCP Bundle sections, package cards

uk/articles/from-tg/architecture/constructor.md новий файл +56 −0

Наскільки складним може бути конструктор?

Якось на курсі php-pro, коли я розповідав про SOLID, один із студентів запитав:

«А скільки залежностей можна вважати нормальним у конструкторі? Три? Чотири? Пʼять — це вже погано?»

Хороше питання. Але відповідь трохи не в площині "цифри".

Є популярна думка, що конструктор має бути максимально простим, бо "інакше це ознака порушення SRP".

Я з цим не згоден. Бо сам факт великої кількості залежностей — не обовʼязково погано: якщо твій обʼєкт має чітку відповідальність, але для її реалізації потребує 6–8 залежностей — це нормально. Проблема, якщо вони несумісні логічно або обʼєкт намагається робити забагато.

Але якщо обʼєкт координує складну, але єдину бізнес-дію — багато залежностей це нормально і навіть правильно.

class OrderFinalizer
{
    public function __construct(
        private OrderRepository $orders,
        private InventoryService $inventory,
        private DiscountCalculator $discounts,
        private TaxService $tax,
        private PaymentGateway $payments,
        private LoggerInterface $logger,
        private EventDispatcherInterface $events,
    ) {}
}

Так, тут 7 залежностей, і всі вони працюють на одну дію — фіналізацію замовлення.

Це SRP у чистому вигляді: складна операція, але одна відповідальність.

Якщо ми почнемо це «розмазувати» по фабриках або передавати 1 загальний сервіс, типу AppContext, — от тоді це буде гірше.

Бо замість явного контракту ти отримуєш непрозору магію.

Незрозуміло, що реально потрібно класу — тільки при читанні коду видно, що витягується з контексту.

Це ускладнює:

  • рефакторинг (бо клас виглядає як чорна діра);
  • тестування (все мокаєш, бо неясно, що саме юзається);
  • зрозумілість (новачок не зчитує залежності по сигнатурі).

Висновок

Не бійся передавати багато залежностей, якщо вони всі потрібні. Бійся ховати залежності в "зручні" обгортки типу AppContext.

Код має бути явним. Це і є архітектура.


Вперше опубліковано в Telegram-каналі «Створений щоб помирати» 19.06.2025.