Эффективно ли мы используем IoC? - PullRequest
16 голосов
/ 22 марта 2010

Таким образом, моя компания использует контейнер Windsor IoC , но в некотором смысле «выключено»:

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

Люди, которые разработали систему, настаивают на том, что контейнер IoC делает систему лучше.У нас более 1200 открытых классов, так что это система big , в которой вы ожидаете, что найдет такую ​​среду, как Windsor.Но я все еще скептически отношусь.

Эффективно ли моя компания использует IoC?Есть ли преимущество для новых объектов с помощью Виндзора перед новыми объектами с ключевым словом new?

Ответы [ 4 ]

23 голосов
/ 22 марта 2010

Краткий ответ: Нет , ваша компания не использует DI эффективно.

Немного более длинный ответ: Основная проблема в том, что все классы имеют конструкторы по умолчанию . Если это так, то как вы разрешаете зависимости?

Либо ваши конструкторы имеют жестко запрограммированные зависимости, подобные этой:

public Foo()
{
    IBar bar = new Bar();
}

В этом случае вы не можете изменять зависимости, не перекомпилировав это приложение.

Еще хуже, они могут использовать анти-шаблон Static Service Locator :

public Foo()
{
    IBar bar = Container.Resolve<IBar>();
}

Контейнер DI должен разрешить весь граф зависимостей в Корне компоновки приложения и убраться с дороги.

В общем случае лучше использовать Convention over Configuration , используя эвристический подход в коде для настройки контейнера. Конфигурация XML должна быть зарезервирована для тех немногих случаев, когда вам необходимо переконфигурировать зависимости без перекомпиляции , которая должна быть только небольшим подмножеством. Короче говоря, я не вижу внутренней проблемы с настройкой контейнера в коде. На самом деле, это предпочтительный подход.

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

3 голосов
/ 22 марта 2010

Все типы данных зарегистрированы в коде, а не в файле конфигурации.

Под типами данных я предполагаю, что вы имеете в виду привязки.Например, IFoo должен быть связан с Foo.Если это так, это нормально.На самом деле, это гораздо лучше для многих людей (включая мое), чем указывать привязки через XML.Естественным преимуществом здесь является то, что во время компиляции выполняются проверки.Вы не будете программировать на XML , как говорится.

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

Вы уверены?Если это так, это может быть запахом.Однако вы заявили, что это большое приложение.Если происходит какое-либо модульное тестирование (или автоматическое тестирование), наличие интерфейса для каждой реализации вполне допустимо.

Эффективно ли моя компания использует IoC?Есть ли преимущество для новых объектов с помощью Виндзора перед новыми объектами с новым ключевым словом?

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

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

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

1 голос
/ 22 марта 2010

Я уверен, что другие будут публиковать более подробные ответы, но вот что я получил:

Все типы данных зарегистрированы в коде, а не в файле конфигурации.

Существует тенденция (, по крайней мере, в некоторых ) IoC / Dependency Injection Framework для регистрации ваших зависимостей с помощью кода, а не XML Config. Основным преимуществом является то, что вы знаете во время компиляции, что-то неправильно написано или нет. Например, если вы решите добавить / удалить аргумент конструктора, ваш код на самом деле не будет компилироваться, когда ваша конфигурация не синхронизирована (и он не дает опечаткам показывать себя как случайные исключения нулевой ссылки во время выполнения).

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

Я не совсем уверен, что вы подразумеваете под "реализацией с одним интерфейсом". Если вы имеете в виду, что интерфейсы передаются объектам, которые их реализуют, то это определенно не кошерно. Если нет, то есть преимущество в кодировании интерфейса, а не конкретной реализации. Основным из них, очевидно, является возможность использовать фиктивные объекты, поддерживающие указанный интерфейс, в модульном тестировании. Программирование на интерфейсе (теоретически) заставляет вас сделать ваш код более свободным, что может помочь в тестировании. Он также открывает некоторые действительно классные варианты дизайна, такие как этот Создание универсального безопасного DAO с Hibernate и Spring AOP one.

Все зарегистрированные типы данных имеют конструктор по умолчанию, поэтому Windsor не создает экземпляр графа объектов для каких-либо зарегистрированных типов.

Это тоже не обязательно плохо. В общем, я думаю, что эмпирическое правило гласит: если для вашего класса критически важна зависимость для выполнения своей функции, то следует использовать внедрение в конструктор. Если нет (логирование, вероятно, является наиболее часто используемым примером этого), то внедрение свойства является более подходящим вариантом. Хотя я не знаком с Castle Windsor, я знаю, что по крайней мере некоторые контейнеры Java IoC не поддерживали внедрение конструкторов в ранних версиях (если кто-то, кто более знаком с Castle Windsor, может прокомментировать это, это было бы здорово). Если бы в Castle Windsor не было этой функции в более ранних версиях, это также могло бы привести к дизайну, который вы видите в своей системе.

Что касается использования IoC против вызова new везде, это также зависит от использования. Несколько проектов, над которыми я работал, в значительной степени основывались на IoC (Spring в Java и Autofac в .NET), а подключение всех моих зависимостей в одном месте позволило нам довольно быстро и безболезненно экспериментировать с иерархиями объектов и их композицией.

0 голосов
/ 22 марта 2010

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

Я бы рассмотрел "Все зарегистрированные типы данных имеют конструктор по умолчанию" как запах кода (при условии, что класс загружает зависимости непосредственно из вашего контейнера IoC). Когда это происходит, это либо 1) точка входа приложения, где уместно получить объект из вашего контейнера Ioc (поскольку вам, вероятно, все равно нужно инициализировать этот контейнер Ioc), либо 2) место, где вы могли бы вместо этого использовать фабрику. 1003 *

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

Похоже, использование IoC в вашей компании в целом неплохое.

...