TGViewer
Пых Пых @phpyh · 7.87K subscribers
Post #972 4.7K
Пых Найдите ошибку в терминологии.
У меня самые умные подписчики в IT 💙 — нашли ошибку за секунды. Ну а для меня этот комментарий стал поводом разложить всё по полочкам.

DI — Dependency Injection

Подход, при котором код явно декларирует необходимые зависимости и получает их снаружи, а не создаёт, не хардкодит и не извлекает их сам.


function logToFile(string $message): void
{
// не DI
file_put_contents(__DIR__ . '/../app.log', $message, FILE_APPEND);
}

final class StreamLogger extends Psr\Log\AbstractLogger
{
public function __construct(
// DI
private string $stream,
) {}

// ...
}


Как видите, зависимостью может быть что угодно, не только интерфейс: строка, число, инстанс финального класса.

Здесь часто проводят параллель с принципом Голливуда («Don’t call us, we’ll call you»): не ищите зависимости, мы их для вас соберём и передадим.

Мне ещё нравится на пальцах объяснять так:
Привет, я A, моя компетенция — α. Чтобы выполнить α, мне потребуются: x, опционально y и кто-то, кто умеет β. Предоставите — всё сделаю. Нет — сорян.


Зависимости можно передавать через конструктор, параметр метода, путём клонирования with-методом (поддерживается в Symfony и Thesis DIC) или через сеттер (не рекомендую, так как мутабельно и можно получить неполный стейт или проблемы похуже в асинхронном сетапе).

DIC — Dependency Injection Container

Сугубо опциональная вещь! Контейнер призван облегчить сборку графа зависимостей в крупном проекте, но никто не мешает собирать приложение руками:


// код в стиле DI, но контейнера нет
$app = new App(
logger: new StreamLogger(__DIR__ . '/../app.log'),
);


Большинство современных библиотек написано в стиле DI, но не требует контейнера. В README как раз обычно и показывают, как всё собрать "на коленке".

DIP — Dependency Inversion Principle

Последний принцип из SOLID. Он призван снизить каплинг и повысить переиспользуемость кода за счёт опоры на абстракции.

Обратите внимание, что в оригинальной формулировке принципа не используется понятие «интерфейс»:

A. High level modules should not depend upon low level modules. Both should depend upon abstractions.

B. Abstractions should not depend upon details. Details should depend upon abstractions.

Robert C. Martin, «The Dependency Inversion Principle», C++ Report, 1996

В C++, о котором идёт речь в статье, не было отдельной языковой конструкции interface: Мартин выражал объектные интерфейсы чисто абстрактными классами. Но в той же статье он отдельно приводит stdio.h как пример Dependency Inversion без всяких классов и виртуальных методов.

В наш StreamLogger тоже можно передать не только путь к локальному файлу:


$stdOutLogger = new StreamLogger('php://stdout');

$compressedLogger = new StreamLogger('compress.zlib:///var/log/app.log.gz');

$remoteLogger = new StreamLogger('ftp://logger:secret@logs.example.com/app.log');


Внезапно для работы с разными потоками нам не потребовался interface! Строковый URI выбирает конкретную реализацию, а StreamLogger работает через общую абстракцию PHP-стримов.

Инверсия зависимостей здесь реализована не в нашем коде, а в PHP: контракт — PHP Streams API, конкретные врапперы — file, php, compress.zlib, ftp и пользовательские протоколы. StreamLogger пользуется этим контрактом, не зная, какая реализация скрывается за URI.

Получается, «абстракция» не тождественна интерфейсу или абстрактному классу. Даже финальный класс может абстрагировать вызывающий код от деталей реализации, пока сохраняет публичный контракт.

И вот тут-то мы и нащупали причину, по которой интерфейс может быть избыточным:

Если тип сам выражает требуемую клиенту стабильную абстракцию и не протекает низкоуровневыми деталями — на него можно опереться напрямую.

🌿 Анонсировали доклады Данилы Щуцкого и Саши Макарова на Пыхнике!
  • 👍 31
  • ❤ 10
  • 🔥 6
  • 💩 5
More from @phpyh
  1. Sep 15, 2026Сейчас один человек с AI может выполнять работу целого IT-отдела. Только хуёво
  2. Sep 12, 2026Спасибо за заявки! Всем напишу в понедельник. Осталось 1 место.
  3. Sep 11, 2026Хардкорный курс асинхронного PHP https://hardcourse.ru/php/async
  4. Sep 11, 2026Ещё полчасика надо — сайт готов, расписываю программу! 🙏
  5. Sep 10, 2026Краткое содержание: завтра в 12:00 открываю набор на Хардкорный курс асинхронного PHP с уч…
  6. Sep 10, 2026Post #1011
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →