Каков реальный пример инъекции зависимостей на динамическом языке?
У меня есть основа в .NET, но в последнее время я использую Python и Ruby. Я подумал, как лучше всего обеспечить зависимости от объектов, которые им нужны в Ruby.
Сначала я думал, что на самом деле я не думал, что рамки DI и IoC должны взаимодействовать с зависимостями из-за снисходительности динамических языков (a la redefinition, mixins, stubs и т.д.). Затем, однако, я столкнулся с ответами относительно того, почему рамки DI/IoC не нужны в динамических языках. Приведенные причины не слишком хорошо сочетаются со мной. Я надеюсь, что смогу увидеть пример, который может прояснить ситуацию.
Рекомендуемые предложения, с которыми я не согласен:
Причина 1: зависимый класс может быть изменен во время выполнения (думаю, тестирование)
В Почему контейнеры IOC не нужны с динамическими языками, мы видим, что зависимый класс (неинжектированный), скажем X
, может быть заглушен или издеваться над контрольная работа. Конечно, но это требует, чтобы мы знали, что наш System Under Test
зависит от того, что называется X
. Если наш System Under Test
внезапно зависит от N
вместо X
, мы должны теперь запомнить N
вместо X
. Преимущество использования DI заключается в том, что мы никогда не будем случайно запускать тест с производственными зависимостями, потому что мы всегда будем проходить в издевающихся зависимостях.
Причина 2: Подкласс или использование инъекции конструктора для тестирования
В каждом любимом ресурсе goto для всех вещей DI + Ruby, LEGOs, Play-Doh и Programming, мы видим пример подкласса система в тесте для издевательства зависимостей. В качестве альтернативы мы можем использовать инъекцию конструктора. Хорошо, поэтому B
зависит от A
. Мы называем B.get_dependency
, который предоставляет B
экземпляр A
. Но что, если A
зависит от N
, которое зависит от X
? Должны ли мы называть get_dependency
для каждого последующего объекта в цепочке?
Причина 3: Зависимости могут быть смешаны или обезврежены
Фабио упоминает, мы можем просто использовать mixins/monkeypatch. Поэтому X
смешивается с N
. Но проблема в том, что, если X
зависит от A
, которое зависит от B
? Мы просто используем mixins для каждой зависимости по цепочке? Я вижу, как это может работать, но может быстро запутаться и запутаться.
Боковое примечание: Многие пользователи говорят, что рамки DI не нужны в динамических языках. Тем не менее, Angular.JS действительно выиграл от реализации довольно солидной системы DI. Angular построен на JavaScript, динамическом языке. Этот подход сопоставим с Ruby или Python?
Пожалуйста, имейте в виду, я не говорю, что хочу заставить DI/IoC в Ruby, Python и т.д.
Ответы
Ответ 1
В то время как многие считают, что DI не нужен, я согласен с вами, что это действительно нужно много; но иногда он смешивается с другими методами, предоставляемыми Python. Я предлагаю вам взглянуть на venusian, это может быть многословным, но если вы пришли из .NET, вы увидите это отношение. Одним словом: venusian позволяет вам аннотировать ваши методы, не изменяя их поведения. Таким образом, вы можете писать венузианские декораторы, чтобы ваше модульное тестирование не пострадало. Pyramid использует venusian для аннотирования представлений, например.