Цими днями у мене в голові спливе запитання:
Чи суперечить нам спосіб Javascript майже всьому, що вважається хорошою практикою в традиційній розробці програмного забезпечення?
У мене є низка запитань / спостережень, пов'язаних з цим твердженням, але для того, щоб поважати формат StackExchange, буде краще, якщо я розділю їх на різні запитання.
Модуль, що вимагає
На сьогодні стандартний код Javascript виглядає так:
const someModule = require('./someModule')
module.exports = function doSomethingWithRequest() {
// do stuff
someModule.someFunc()
// do other stuff
}
Переваги
- Інкапсуляція: модуль працює автономно і знає все, що потрібно для виконання його функцій.
- Як кольоровий, клієнтам простіше використовувати модуль.
Недоліки
- Погана перевіряемость: це звичайно, коли не використовується DI, але в динамічних мовах, таких як Javscript, його можна обійти * модулями, як
mockery
абоrewire
. - Це, безумовно, порушує DIP - не плутати з введенням залежності. - оскільки я можу імпортувати лише конкретні модулі.
- Це, ймовірно, порушує OCP - наприклад, уявіть, що у мене є модуль журналу, який записує у файлову систему (через
fs
модуль). Якщо я хочу розширити цей модуль журналу, щоб надіслати його в мережу, було б дуже важко.
* Це може працювати з CommonJS або навіть модулями AMD, оскільки вони в основному реалізовані в країні користувачів. Однак я не впевнений, як це могло бути можливим із import
синтаксисом ES6 .
Ін'єкційна залежність
Використовуючи ін'єкційну залежність, це було б більше як:
module.exports = function doSomethingWithRequest(someModule) {
// do stuff
someModule.someFunc()
// do other stuff
}
Переваги
- Підвищена заповідність: тепер легше
someModule
заглушити / знущатися , навіть використовуючи синтаксис ES6. - Це можна шанувати DIP: не обов'язково , хоча, як клієнтський модуль все ще може бути запрограмований для реалізації і не інтерфейс.
Недоліки
- Розбита інкапсуляція: головне питання, що залишається:
Добре, тоді хто буде створювати / вимагати залежності?
- Це в кожному клієнті модуля здається дуже мокрим .
- Це, можливо, вимагає від мене використовувати контейнер DI, щоб це було можливо в реальному проекті.
Отже, справжнє питання тут:
Чому розробники Javascript схиляються до першого підходу?
Це просто "шлях Javascript"?
Я сам пишу такий код більшу частину часу. Я мав свою частку тестових налаштувань з використанням насмішкувальних бібліотек, але це завжди було не так.
Я щось пропускаю?