Антипаттерн DI Control-Freak: проблемы с пониманием

Я читаю «Внедрение зависимостей в .NET» Марка Симанна, и я не могу на всю жизнь обдумать это:

Хотя ключевое слово new является запахом кода, когда речь идет о VOLATILE DEPENDENCIES, вам не нужно беспокоиться об его использовании для STABLE DEPENDENCIES. Ключевое слово new не является вдруг «незаконным» в целом, но вам следует воздерживаться от его использования для получения экземпляров VOLATILE DEPENDENCIES.

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

Я бы очень хотел понять DI от начала до конца, но сейчас я застрял, и это всего лишь 1/3 книги... Антипаттерн Control-Freak, кажется, есть у каждого программиста, который когда-либо жил. ...

У кого-нибудь есть идеи?


person Grixxly    schedule 04.07.2012    source источник
comment
См. jamesshore.com/Blog/Dependency-Injection-Demystified.html. Вокруг так много слишком сложных статей о DI, хотя на самом деле это не так уж и много. Я нашел статью весьма поучительной :-).   -  person helpermethod    schedule 04.07.2012


Ответы (3)


Волатильность (для меня) — это мера вероятности того, что класс нужно будет изменить.

В идеале вы проектируете классы так, чтобы они были открыты для расширения, но закрыты для модификации (принцип открытости и закрытости). Это не всегда возможно. Те классы, которые вы близки к изменению, менее изменчивы, чем остальные.

NDepend (инструмент метрик статического анализа .Net) имеет метрику под названием Instability, которая в моем ум синоним. Они определяют это как:

Нестабильность (I): отношение эфферентной связи (Ce) к общей связи. I = Се / (Се + Са). Этот показатель является индикатором устойчивости сборки к изменениям. Диапазон этого показателя составляет от 0 до 1, где I=0 указывает на полностью стабильную сборку, а I=1 указывает на полностью нестабильную сборку.

Вы не хотите, чтобы стабильные классы полагались на менее стабильные.

Что касается решения вводить или нет, это больше похоже на проблему роли класса. Из доменно-управляемого дизайна (DDD) классы обычно являются либо сущностями (у них есть идентичность), сервисами (они организуют вещи), либо значениями (они неизменны и сопоставимы, например, RED или 100ml).

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

person Nigel Thorne    schedule 05.07.2012

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

Стабильная зависимость — это зависимость, конкретная реализация которой не будет меняться ни по классу, ни по конфигурации, с течением времени или в разных ситуациях.

Изменчивая зависимость — это зависимость, конкретная реализация которой может меняться в классе или конфигурации с течением времени или в разных ситуациях.

Если вы можете простить пример на Java, стабильной зависимостью будет StringBuilder. Если вы пишете метод для создания строки, вам не нужно вводить StringBuilder, вы можете просто создать его. То же самое для ArrayList, HashMap и т. д. Помимо стандартных библиотечных классов, если вы пишете банковское приложение, вы, вероятно, не будете внедрять RunningTotaliser, потому что это объект, который просто суммирует для вас числа.

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

person Tom Anderson    schedule 04.07.2012

Обычно контейнер DI разрешает все зависимости для конкретной реализации и обрабатывает время жизни для вас. Но DI Control-Freak делает наоборот: создает конкретный объект с помощью ключевого слова new, внедряет их и сам обрабатывает время жизни. Таким образом, никто другой не имеет возможности настраивать и обрабатывать зависимости вне вашего кода. И, таким образом, повторно используйте или тестируйте его, предоставляя другие реализации или подделки.

Вот цитата из книги @mark-seemann, которая отвечает на ваш вопрос:

Я назвал его CONTROL FREAK, чтобы описать класс, который не откажется от контроля над своими ЗАВИСИМОСТЬМИ.

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

person Akim    schedule 04.07.2012