DI Control-Freak anti-pattern: проблемы с пониманием
Я читаю инъекцию зависимостей в .NET от Марка Seemann, и я не могу за всю свою жизнь обернуть голову вокруг этого:
хотя новая ключевое слово-это запах кода, когда дело доходит до VOLATILE Зависимости, вам не нужно беспокоиться об использовании его для стабильной ЗАВИСИМОСТИ. The новая ключевое слово не внезапно "незаконно" в целом, но вы должны воздержаться от использования его для получения экземпляров VOLATILE ЗАВИСИМОСТИ.
может быть, это потому, что я все еще не могу понять, что окружающий контекст-это инъекция, а не просто глобальная переменная, но я просто не понимаю, что говорит автор.
Я бы очень хотел понять Ди сверху донизу, но прямо сейчас я застрял, и это всего лишь 1/3 пути через книгу... Анти-паттерном, помешанным на контроле, кажется, является каждый программист, который когда-либо жил...
У кого-нибудь есть озарения?
3 ответов
волатильность (для меня) является мерой вероятности того, что класс нужно будет изменить.
В идеале вы разрабатываете классы, открытые для расширения, но закрытые для модификации (открытый закрытый принцип). Это не всегда возможно. Те классы, которые вы близки к изменению, менее изменчивы, чем другие.
NDepend (инструмент метрик статического анализа .Net) имеет метрику нестабильность это в моем сознании синонимично. Они определяют это как:
нестабильность (I): отношение эфферентной муфты (Ce) к общей муфте. I = Ce / (Ce + Ca). Этот показатель является показателем устойчивости сборки к изменениям. Диапазон для этой метрики от 0 до 1, при этом I=0 указывает на полностью стабильную сборку, а I=1 указывает на полностью нестабильную сборку.
вы не хотите, чтобы стабильные классы полагались на менее стабильные.
Что касается решения вводить или нет, это больше похоже на класс ролевой вопрос. Из Domain Driven Design классы (DDD) обычно являются либо сущностями (у них есть удостоверение), либо службами (они организуют вещи), либо значениями (они неизменяемы и сопоставимы, например RED или 100ml).
вы бы вводили службы, вы бы вызывали новые значения. Сущности обычно поступают из репозитория (который вы вводите), но внутренне репозиторий будет вызывать new на них. Это поможет?
Я не слышал этих терминов раньше, но транспонируя то, что я знаю об инъекции зависимостей, я бы определил их следующим образом.
стабильная зависимость-это та, конкретная реализация которой не будет меняться в классе или конфигурации, со временем или в разных ситуациях.
изменчивая зависимость-это та, конкретная реализация которой может изменяться в классе или конфигурации, со временем или в разных ситуациях.
если вы можете простить пример в Java стабильная зависимость будет StringBuilder
. Если вы пишете метод для создания строки, вам не нужно иметь StringBuilder
injected, вы можете просто создать его. То же самое для ArrayList
, HashMap
, etc. Помимо стандартных классов библиотеки, если бы вы писали банковское приложение, вы, вероятно, не вводили бы RunningTotaliser
, потому что это объект, который просто добавляет числа для вас.
примеры изменчивых зависимостей в стандартной библиотеке сложнее придумать. Классический пример: а DataSource
- это объект, который инкапсулирует сведения о соединении для базы данных, и они почти наверняка не должны предоставляться кодом, который фактически делает соединения.
обычно контейнер DI разрешает все зависимости для конкретной реализации и обрабатывает время жизни для вас. Но!--2-- > DI Control-урод совсем наоборот: создает конкретный объект, используя new
ключевое слово, вводит их и обрабатывает время жизни только сам. Таким образом, никто другой не имеет возможности настраивать и обрабатывать зависимости вне вашего кода. И, таким образом, повторно использовать или тестировать его, предоставляя другие реализации или подделки.
вот цитата из книги @mark-seemann, что отвечает на ваш вопрос:
Я назвал его control FREAK, чтобы описать класс, который не будет отказаться от контроля над его зависимостями.
это происходит каждый раз, когда мы создаем новый экземпляр типа с помощью нового ключа- слово. Когда мы это делаем, мы явно заявляем, что будем контролировать время жизни экземпляр и что никто другой не получит шанс перехватить этот конкретный объект.