Аргументы конструктора класса ES6 более чем требуют - PullRequest
0 голосов
/ 20 марта 2019

При использовании классов ES6, почему бы вам не передать зависимости через конструктор вместо того, чтобы перечислять их как импорт / требование вверху: например,

class DEF {
  constructor(ABC) {
    this.abc = new ABC();
  }
}

вместо

const ABC = require('./abc');

class DEF {
  constructor() {
    this.abc = new ABC();
  }
}

Я пытаюсь понять разницу между этими стилями программирования и последствиями обоих?

Ответы [ 4 ]

2 голосов
/ 20 марта 2019

Это форма Внедрение зависимости , которая может быть полезна в различных случаях.Например, для тестирования.

Обычно вы делаете что-то вроде

const DefaultABC = require('./abc');

class DEF {
  constructor(ABC = DefaultABC) {
    this.abc = new ABC();
  }
}

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

0 голосов
/ 20 марта 2019

Это очень зависит от варианта использования.Вопрос здесь заключается в том, где находится принятие решения?

Если ваша задача - решить, какой метод-прототип использовать для создания экземпляра нового объекта?Или вы хотите, чтобы вызывающая сторона решала, какой метод-прототип использовать?Эти вопросы должны быть заданы и продуманы при разработке приложения, а обязанности должны быть распределены на основе разногласий по проекту.

Возьмем, к примеру, простое дополнение:

1 + 1 //=> 2
1 + '1' //=> '11'

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

1.add(1, Number) //=> 2
1.add('1', Number) //=> 2
1.add(1, String) //=> '11'

Ни то, ни другое не является правильным или неправильным.

0 голосов
/ 20 марта 2019

В первом примере вы можете использовать разные версии ABC, при условии, что они реализуют один и тот же интерфейс.Это обеспечивает более слабую связь, чем последняя, ​​с недостатком, который требует полного знания того, как DEF будет внутренне использовать ABC, чтобы убедиться, что интерфейсы совпадают.

Во втором примере вам не нужно беспокоиться о том, какая версияABC используется.Оба класса теперь тесно связаны друг с другом, с преимуществом только необходимости знать, как работает DEF, знание ABC не требуется.

Таким образом, оба «стиля» решают разные проблемы imho.

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

0 голосов
/ 20 марта 2019

Потому что иногда имеет смысл переходить в разные классы:

new Vehicle(/*for*/ Animal)
new Vehicle(/*for*/ Human)
...