0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>На протяжении всего курса, мы говорили про процесс инициализации, внутри которого создаются необходимые объекты. Затем эти объекты используются в прикладном коде. К таким объектам относятся: соединение с базой данных, логгер, кеш, шаблонизатор, интеграция с внешними сервисами и многое другое.</p>
1
<p>На протяжении всего курса, мы говорили про процесс инициализации, внутри которого создаются необходимые объекты. Затем эти объекты используются в прикладном коде. К таким объектам относятся: соединение с базой данных, логгер, кеш, шаблонизатор, интеграция с внешними сервисами и многое другое.</p>
2
<p>В простых ситуациях, там где объектов немного и мы сами управляем кодом (а не используем фреймворки, определяющие структуру), зависимости можно внедрять "руками":</p>
2
<p>В простых ситуациях, там где объектов немного и мы сами управляем кодом (а не используем фреймворки, определяющие структуру), зависимости можно внедрять "руками":</p>
3
<p>В коде, который активно использует инверсию зависимостей, инициализация кода выглядит как матрешка из объектов. Объекты верхнего уровня принимают на вход объекты с нижних слоев, шаг за шагом собирая готовое приложение.</p>
3
<p>В коде, который активно использует инверсию зависимостей, инициализация кода выглядит как матрешка из объектов. Объекты верхнего уровня принимают на вход объекты с нижних слоев, шаг за шагом собирая готовое приложение.</p>
4
<p>С ростом числа объектов, процесс сборки усложняется и становится утомительным. Появляются ситуации, в которых объекты нужны в самой глубине кода, но прокинуть их можно только пройдя множество уровней. В популярных фреймворках инициализация может включать в себя создание и внедрение сотен объектов. Страшно даже представить, что придется писать этот код вручную.</p>
4
<p>С ростом числа объектов, процесс сборки усложняется и становится утомительным. Появляются ситуации, в которых объекты нужны в самой глубине кода, но прокинуть их можно только пройдя множество уровней. В популярных фреймворках инициализация может включать в себя создание и внедрение сотен объектов. Страшно даже представить, что придется писать этот код вручную.</p>
5
<p>Для решения данной задачи, используется два подхода (шаблона проектирования). Ниже поговорим про каждый из них</p>
5
<p>Для решения данной задачи, используется два подхода (шаблона проектирования). Ниже поговорим про каждый из них</p>
6
<h2>Локатор (Service Locator)</h2>
6
<h2>Локатор (Service Locator)</h2>
7
<p>Самый простой способ внедрять зависимости в таких системах - сервис локатор. Это объект, который содержит внутри себя все зависимости. Любой объект, которому нужен какой-либо сервис, обращается за ним к сервис локатору.</p>
7
<p>Самый простой способ внедрять зависимости в таких системах - сервис локатор. Это объект, который содержит внутри себя все зависимости. Любой объект, которому нужен какой-либо сервис, обращается за ним к сервис локатору.</p>
8
<p>Возьмем для примера микрофреймворк Fastify из JS. У него есть расширение, которое добавляет шаблонизатор в фреймворк. Попробуем внедрить шаблонизатор Pug через Service Locator:</p>
8
<p>Возьмем для примера микрофреймворк Fastify из JS. У него есть расширение, которое добавляет шаблонизатор в фреймворк. Попробуем внедрить шаблонизатор Pug через Service Locator:</p>
9
<p>Вот такой нехитрый подход для внедрения зависимостей. По нему написаны сотни статей со всевозможными вариациями его создания и использования. В большинстве из них локатор рассматривается как антипаттерн. Так как прикладной код знает про его существование.</p>
9
<p>Вот такой нехитрый подход для внедрения зависимостей. По нему написаны сотни статей со всевозможными вариациями его создания и использования. В большинстве из них локатор рассматривается как антипаттерн. Так как прикладной код знает про его существование.</p>
10
<h2>Контейнер (DI Container)</h2>
10
<h2>Контейнер (DI Container)</h2>
11
<p>Вершиной эволюции инверсии зависимостей считается DI Container. Продвинутые контейнеры, это целые фреймворки, которые занимаются инициализацией приложения, собирают необходимые объекты и прокидывают их друг в друга. В некоторых экосистемах, контейнер - центральная часть всей системы, которая занимается ее оркестрацией (управлением). В Java, например, это Spring Framework. Он с легкостью может собирать и веб-приложение и демонов.</p>
11
<p>Вершиной эволюции инверсии зависимостей считается DI Container. Продвинутые контейнеры, это целые фреймворки, которые занимаются инициализацией приложения, собирают необходимые объекты и прокидывают их друг в друга. В некоторых экосистемах, контейнер - центральная часть всей системы, которая занимается ее оркестрацией (управлением). В Java, например, это Spring Framework. Он с легкостью может собирать и веб-приложение и демонов.</p>
12
<p>Ключевое отличие контейнера от локатора в том, что зависимости из контейнера попадают внутрь приложения прозрачно. Прикладной код не догадывается о существовании контейнера, он лишь видит объекты, которых ждет. Для инъекции этих зависимостей используются стандартные подходы: либо через конструктор, либо через сеттеры и аргументы методов.</p>
12
<p>Ключевое отличие контейнера от локатора в том, что зависимости из контейнера попадают внутрь приложения прозрачно. Прикладной код не догадывается о существовании контейнера, он лишь видит объекты, которых ждет. Для инъекции этих зависимостей используются стандартные подходы: либо через конструктор, либо через сеттеры и аргументы методов.</p>
13
<p>Снова посмотрим на Fastify и интеграцию с Pug, но уже через встроенный контейнер. Для внедрения зависимости фреймворк имеет метод register():</p>
13
<p>Снова посмотрим на Fastify и интеграцию с Pug, но уже через встроенный контейнер. Для внедрения зависимости фреймворк имеет метод register():</p>
14
<p>Обработчик запроса получает метод отрисовки через метод view(). Обработчик не знает ничего про контейнер и про то, как зависимость попала внутрь приложения.</p>
14
<p>Обработчик запроса получает метод отрисовки через метод view(). Обработчик не знает ничего про контейнер и про то, как зависимость попала внутрь приложения.</p>