Это вторая часть из трех частей, посвященных внедрению зависимостей в Node.

Мир состоит не только из фу-бара и псевдокода. Это очень подлое и противное место ...

Позвольте мне подготовить почву для нашего воображаемого, совершенно оригинального проекта, о котором никто никогда раньше не думал: Приложение Todo О, да. Подана заявка на патент…

Прежде чем мы перейдем к фреймворкам API и тому подобному, давайте просто напишем суть приложения - сервис и доступ к данным. Я буду использовать ES7 async-await для удобства чтения (и потому что это круто).

Начнем со службы Todos - она ​​обрабатывает всю «бизнес-логику», например, изолирует доступ к задачам конкретного пользователя.

Я буду писать эти фрагменты в разных стилях (функциональных и ориентированных на классы), чтобы доказать, что это не имеет значения! Используйте то, что вам больше нравится!

todosService.js

Немного длинно, но ничего особенного там не происходит. Мы не зависим от каких-либо внешних библиотек (кроме встроенного модуля assert для добавления проверок работоспособности). Однако наша экспортированная функция имеет 2 зависимости:

  • todosRepository - объект, который дает нам доступ к базе данных задач (что бы это ни было, нам все равно).
  • currentUser - пользователь, использующий службу. Помните, мы не знаем, откуда это! Нам все равно!

Продолжаем, давайте создадим реализацию этого сладкого сладкого репозитория todos!

todosRepository.js

Это просто реализация в памяти репозитория задач, используемого службой. Когда мы будем готовы, мы можем заменить его на MySQL, Rethink, MongoDB, WhateverDB, который вы хотите, при условии, что API останется прежним. Здесь действительно сияют такие инструменты, как TypeScript и Flow.

Сшиваем систему вместе

Прежде чем приступить к написанию настоящего REST API, давайте просто попробуем объединить все вместе в тесте. Этот подход называется DI для бедняков - не волнуйтесь, я расскажу вам позже!

Вы могли подумать: «Но Джефф! Теперь этот код знает об обоих модулях! » - это правда, и в реальном приложении (к которому мы вернемся через минуту) должен быть единственный источник правды, который знает обо всех используемых модулях - те из нас, кто надевает модные штаны DI. есть имя для этого святого места: Корень Композиции. Это единое место в приложении, которое связывает все воедино - оно составляет ваши модули! Хотите заменить этот todosRepository в памяти на реализацию RethinkDB? Здесь вы можете сделать swippety swappety.

Корень композиции может выглядеть так.

композицияRoot.js

Я знаю, я знаю, о чем вы думаете! «Я еще не знаю, кто этот пользователь, я создаю веб-приложение! Это бесполезно! » Вы абсолютно правы. Есть два способа решить эту проблему вручную:

  • Передайте currentUser всем методам, которые в нем нуждаются - отстой.
  • Отложите создание экземпляров вещей до тех пор, пока не получите все необходимые данные - это тоже отстой, потому что теперь вам нужно создавать экземпляры вещей в нескольких местах.

Чтобы дать вам представление о том, как будет работать второй подход, и насколько он отстой, вот как мы могли бы это сделать. В этом примере используется Koa Router.

И это всего с 2 модулями! Представьте, что их было 10 (и это только для небольшого приложения). Ага, отстой.

Таким образом, мы все можем согласиться с тем, что выполнение DI вручную в крупномасштабном приложении, таком как наше замечательное мультитенантное приложение, просто не сработает для нас. Давай просто сдадимся и вернемся к требованиям. Хорошего дня.

… или нет! Прочтите часть 3 и исправьте этот беспорядок!