Модуль, требующий внедрения зависимостей в Javascript


24

В эти дни у меня возник вопрос:

Идет ли то, как мы, Javascript, против всего, что считается хорошей практикой в ​​традиционной разработке программного обеспечения?

У меня есть ряд вопросов / замечаний, связанных с этим утверждением, но для того, чтобы уважать формат StackExchange, будет лучше, если я разделю их на разные вопросы.

Модуль, требующий

Стандартный код Javascript в настоящее время выглядит так:

const someModule = require('./someModule')

module.exports = function doSomethingWithRequest() {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

преимущества

  • Инкапсуляция: модуль работает автономно и знает все, что нужно для выполнения своих функций.
  • Как клиент, клиентам проще использовать модуль.

Недостатки

  • Плохая тестируемость: это стандартно, когда не используется DI, но в динамических языках, таких как Javscript, его можно обойти * с помощью таких модулей, как mockeryили rewire.
  • Это, безусловно, нарушает DIP - не путать с Dependency Injection. - поскольку я могу импортировать только конкретные модули.
  • Это, вероятно, нарушает OCP - например, представьте, что у меня есть модуль журнала, который пишет в файловую систему (через fsмодуль). Если я захочу расширить этот модуль журнала для отправки его в сеть, это будет очень сложно.

* Это может работать с модулями CommonJS или даже AMD, поскольку они в основном реализованы в пользовательской среде. Однако я не уверен, как это может быть возможно с importсинтаксисом ES6 .

Внедрение зависимости

Используя внедрение зависимостей, это было бы больше похоже на:

module.exports = function doSomethingWithRequest(someModule) {
  // do stuff
  someModule.someFunc()
  // do other stuff
}

преимущества

  • Повышенная тестируемость: теперь проще заглушки / макеты someModule, даже используя синтаксис ES6.
  • Это можно чтить DIP: не обязательно , хотя, как клиентский модуль все еще может быть запрограммирован для реализации и не интерфейс.

Недостатки

  • Нарушенная инкапсуляция: главный вопрос остается:

    Хорошо, тогда кто будет создавать / требовать зависимости?

  • Выполнение этого в каждом клиенте модуля кажется очень влажным .
  • Это, вероятно, потребовало бы от меня использования DI-контейнера, чтобы это было осуществимо в реальном проекте.

Итак, настоящий вопрос здесь:

Почему разработчики Javascript склоняются к первому подходу?

Это просто «путь Javascript»?

Я сам пишу такой код большую часть времени. У меня была справедливая доля тестовой установки с использованием насмешливых библиотек, но это всегда казалось неправильным.

Я что-то пропустил?


Как парень .Net, который недавно заинтересовался NodeJ, я тоже с этим боролся. Я нашел обезьяну зашивки зависимостей с Proxyquire (так же, как ReWire) , чтобы быть в порядке для целей тестирования, но иногда законные потребности несколько реализаций в зависимости ...
RubberDuck

Ответы:


6

Я в основном программист на PHP, но в течение последнего года общался с 4 командами JavaScript.

Как объектно-ориентированному программисту принцип внедрения зависимостей мог бы показаться наилучшим, однако несколько JS-разработчиков говорили мне иначе. JS - это совершенно другой мир.

Поскольку JavaScript позволяет легко и просто исправлять все и вся, используя очень простые методы, разработчики JavaScript научились адаптировать различные технологии для создания более масштабных приложений JavaScript. Большинство из них построены как наборы автономных модулей, которые демонстрируют функциональность через открытый экспорт, скрывая внутренние компоненты модуля, чтобы не позволить другим переписать функции, на которые вы полагаетесь.

Обычный подход, как правило, заключается в том, чтобы даже не раскрывать конструктор, а просто показывать конструирование объекта с использованием фабричной обертки - по той же самой причине: если вы даете кому-то доступ к объекту, он может непосредственно создать экземпляр объекта. разрешено что-либо менять.

Воспользовавшись модульным дизайном, вы отказываете другим играть с вашими функциями, которые вы ожидаете работать, но у вас все еще есть возможность тестировать свои модули - через открытый API требуемого файла, API, который вы создали.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.