Получи случайную криптовалюту за регистрацию!

?-> вместо NullObject: по следам дискуссии Предыдущий пост бу | Пых

?-> вместо NullObject: по следам дискуссии

Предыдущий пост бурно и полезно обсудили, расписываю основные мысли.

"За" и "против" использования ?-> для опциональных зависимостей:
самый лаконичный способ до выхода PHP 8.1 (там можно будет использовать new для значений параметров по умолчанию);
обходится дешевле в рантайме, так как в null-сценарии выполняется меньше кода (сразу оговорюсь, что это вообще сомнительный аргумент, в частности, трудно себе представить приложение без логгирования в продакшне);
скрытый и "ненужный" if;
NullObject — более корректное и универсальное с точки зрения ООП решение, null-safe подход может быть уместен только в нескольких случаях;
на проекте без статического анализатора вероятность ошибки выше.

Также в Пыхтелке затронули очень важную тему: зависимости редко бывают опциональными. Действительно, nullable зависимости часто сигнализируют о нарушении SRP. Необязательные поведения лучше оформлять в виде декораторов или middleware — их легко включать и выключать, не изменяя код (см. OCP).

Что касается логгирования, его не всегда можно представить в виде декоратора. Зачастую полезная для логов информация инкапсулирована в реализации и не протекает через контракт. Скорее всего, в этом случае тоже где-то нарушается SRP, но добавление абстракции исключительно ради логгирования может быть неоправданным усложнением.

И последний нюанс: зачем вообще делать логгер опциональной зависимостью, если он всегда есть в контейнере? Мой ответ простой: лень. В юнит-тестах, не тестирующих само логгирование, не хочется каждый раз писать new Service(/** required dependencies, */ new NullLogger()) .

Итак, теперь мы знаем, что можно вот так нестандартно использовать ?->, но что это не всегда хорошая идея. Всем спасибо за комментарии!