Приводят ли структуры Dependency Injection к плохому / ленивому дизайну? - PullRequest
3 голосов
/ 05 февраля 2009

Я довольно новичок в концепции DI, но я до некоторой степени использовал ее в своих проектах - главным образом, «внедряя» интерфейсы в конструкторы и заставляя фабрики создавать мои конкретные классы. Хорошо, это не основано на конфигурации - но это никогда НЕ ДОЛЖНО быть.

Я начал изучать DI-фреймворки, такие как Spring.NET и Castle Windsor, и наткнулся на этот блог от Ayende.

Что я получил от этого

A) Фреймворки DI потрясающие, но Б) Это означает, что нам не нужно беспокоиться о том, как наша система спроектирована с точки зрения зависимостей.

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

Я немного боюсь потерять этот контроль, и это просто для всех. ClassA нужен ClassB = нет проблем, просто спросите, и вы получите! Хммм.

Или в этом суть, и это будущее, и я должен просто пойти с этим?

Мысли

Ответы [ 8 ]

9 голосов
/ 05 февраля 2009

Один из основных принципов ОО заключается в том, что вы хотите, чтобы ваш код зависел от интерфейсов, а не от реализаций, именно так мы поступаем в DI. Исторически сложилось так:

  1. Люди изначально создали классы, от которых они зависели, "new'ing" их:

    IMyClass myClass = new MyClass ();

  2. Затем мы хотели удалить инстанцирование, чтобы были статические методы для их создания:

    IMyClass myClass = MyClass.Create ();

  3. Тогда мы больше не зависели от жизненного цикла класса, но все еще зависели от него для реализации, поэтому мы использовали фабрику:

    IMyClass myClass = MyClassFactory.Create ();

  4. Это переместило прямую зависимость от потребляющего кода к фабрике, но у нас все еще была зависимость от MyClass косвенно, поэтому мы использовали шаблон локатора службы следующим образом:

    IMyClass myClass = (IMyClass) Context.Find ("MyClass");

  5. Таким образом, мы зависели только от интерфейса и имени класса в нашем коде. Но это может быть сделано лучше, почему бы не зависеть просто от интерфейса в нашем коде? Мы можем с внедрением зависимости. Если вы используете внедрение свойств, вы просто добавляете в свой код установщик свойств для нужного интерфейса. Затем вы настраиваете фактическую зависимость вне вашего кода, а контейнер управляет жизненным циклом этого класса и вашего класса.

7 голосов
/ 05 февраля 2009

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

Вам все еще нужно подумать о том, какие интерфейсы вам нужны, и правильно их настроить не всегда тривиально.

Я не понимаю, как слабосвязанную систему можно считать лениво спроектированной. Если вы столкнетесь со всеми проблемами, связанными с изучением инфраструктуры IoC, вы, безусловно, не воспользуетесь этим ярлыком.

3 голосов
/ 05 февраля 2009

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

На самом деле, попытка использовать контейнер, вероятно, покажет вам, что ваша система не так слабо связана, как вы думали ... поэтому, таким образом, это может помочь вам создать лучший дизайн.

Ну, я новичок в этом деле ... так что, возможно, я не прав.

Приветствие.

1 голос
/ 06 февраля 2009

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

Если они следуют духу и проводят тесты, они еще больше улучшат ваши компоненты. Оба упражнения заставляют вас лучше писать тестируемые компоненты, которые очень хорошо сочетаются с тем, как работают контейнеры IOC.

1 голос
/ 05 февраля 2009

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

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

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

1 голос
/ 05 февраля 2009

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

Как внедрение зависимостей делает вас ленивым, может быть, это заставляет кого-то другого иметь дело с зависимостями? В этом весь смысл! То, что кому-то другому не нужно быть действительно кем-то другим; это просто означает, что код, который вы пишете, не должен быть связан с зависимостями, потому что он объявляет их заранее. И ими можно управлять, потому что они явные.

Редактировать: добавлено последнее предложение выше.

0 голосов
/ 19 февраля 2009

Мы написали специальную структуру DI, думали, что это заняло некоторое время, но все это стоило усилий. Мы разделили системы who на слои, и внедрение зависимостей в каждом слое связано правилами. Например. На уровне журнала интерфейсы CUD и BO не могут быть введены.

Мы все еще размышляем над правилами, и некоторые из них меняются каждую неделю, в то время как другие остаются неизменными.

0 голосов
/ 06 февраля 2009

Ты все еще должен волноваться. Моя команда использует Castle Windsor в нашем текущем проекте. Меня раздражает, что он задерживает поиск зависимостей от времени компиляции до времени выполнения.

Без Castle Windsor вы пишете код, и если вы еще не разобрали свои зависимости. Взрыв, компилятор будет жаловаться. С помощью Castle Windsor вы настраиваете зависимости в XML-файле. Они все еще там, просто отделены от основной части вашего кода. Проблема в том, что ваш код может хорошо скомпилироваться, если вы запутались в определении зависимостей. Но во время выполнения Castle Windsor ищет конкретные классы для обслуживания запросов интерфейса, используя отражение. Если зависимость не может быть найдена, вы получите ошибку во время выполнения.

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

Так что ... в любом случае. Зависимости все еще имеют большое значение. Вы наверняка будете уделять им больше внимания при использовании DI, чем раньше.

...