Почему контейнеры МОК являются ненужными с динамическими языками

Кто-то на Пасущемся подкасте Кода № 68, http://herdingcode.com/herding-code-68-new-year-shenanigans/, заявил, что контейнеры МОК не имели никакого места с Python или JavaScript или словами к тому эффекту. Я предполагаю, что это - расхожее мнение и что оно относится ко всем динамическим языкам. Почему? Что о динамических языках делает контейнеры МОК ненужными?

42
задан mikemay 11 March 2018 в 17:01
поделиться

6 ответов

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

В статических языках, когда вы ссылаетесь на класс по имени (чтобы вызвать new на нем), нет никакой двусмысленности. Это жесткая связь с конкретным классом.

В динамических языках вызов new X - это место для "инстанцирования любого класса, определенного как X в момент выполнения". Это более слабая связь, поскольку она связана только с именем X.

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

Однако лично я считаю, что у IoC есть два преимущества, которые я не получаю, полагаясь на динамический язык для разрешения инъекций.

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

Другой результат - наличие явного кода для выполнения проводки. Правильно выполненный, он четко представляет структуру вашего приложения и его декомпозицию на подсистемы и жизненные циклы. Это заставляет людей явно решать, с каким жизненным циклом или подсистемой они хотят связать свой класс (при написании кода проводки), и концентрироваться на поведении объекта при написании класса.

Как сказал Йорг В. Миттаг. "Эти инструменты не нужны, принципы проектирования - нет". Я считаю, что они не нужны, но если все сделано правильно, то все равно ценны.

46
ответ дан 26 November 2019 в 23:22
поделиться

Потому что они уже встроены в язык.

Контейнер IoC обеспечивает две вещи:

  • динамическое связывание
  • динамический язык (обычно очень дрянной, построенный на основе XML или в более новых версиях поверх аннотаций Java / атрибутов .NET)

Динамическое связывание уже является частью динамического языка, а динамический язык уже является динамическим языком. Следовательно, контейнер IoC просто не имеет смысла: язык уже является контейнером IoC.

Другой способ взглянуть на это: что позволяет делать контейнер IoC? Это позволяет вам взять независимые компоненты и связать их вместе в приложение, при этом ни один из компонентов ничего не знает друг о друге. Есть название для объединения независимых частей в приложение: сценарии! (Это в значительной степени определение сценариев.) Многие динамические языки также неплохо справляются с написанием сценариев, поэтому они идеальны в качестве контейнеров IoC.

Обратите внимание, что я не говорю о внедрении зависимостей или инверсии управления. DI и IoC так же важны для динамических языков, как и для статических, по точно таким же причинам. Я говорю о контейнерах IoC и фреймворках DI. Эти инструменты не нужны, принципы проектирования - нет.

17
ответ дан 26 November 2019 в 23:22
поделиться

Одной из основных особенностей контейнеров IOC является то, что вы можете автоматически «связывать» свои модули вместе во время выполнения. В динамических языках это можно сделать довольно легко без какой-либо сложной логики, основанной на отражении. Однако контейнеры IOC - это полезный шаблон, который понимают многие люди, и иногда может быть полезно использовать один и тот же стиль дизайна. См. эту статью для получения другой точки зрения.

3
ответ дан 26 November 2019 в 23:22
поделиться

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

Я не разделяю мнения о том, что динамический язык устраняет необходимость в четко структурированной композиции объектов. Или что динамический язык «предоставляет» ту же функциональность.

Контейнер IOC - это просто инструмент для управления этой организацией.

Даже в динамическом языке я хочу «связать» компоненты вместе. Без жестких зависимостей между этими компонентами. Или, может быть, даже без указания фактического класса реализации для этих компонентов.

25
ответ дан 26 November 2019 в 23:22
поделиться

Контейнеры IoC действительно позволяют создать композиционный слой в статически типизированных, процедурных/ОО языках.

Этот композиционный слой существует относительно естественно в динамических языках, таких как Python или Javascript (учтите, что Javascript в значительной степени основан на Scheme).

Вероятно, можно привести хороший аргумент, что контейнеры IoC - это просто обобщение паттерна Interpreter.

3
ответ дан 26 November 2019 в 23:22
поделиться

Herding Code 82 (06.06.10) сравнивает Ruby с .NET и включает подробное обсуждение того, в какой степени .NET требует больше IOC / DI, чем Ruby.

0
ответ дан 26 November 2019 в 23:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: