Подтвердить что ты не робот

Мы эффективно используем IoC?

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

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

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

Является ли моя компания эффективной IoC? Есть ли преимущества для новых объектов с Windsor, чем с новыми объектами с ключевым словом new?

4b9b3361

Ответ 1

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

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

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

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

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

Хуже того, они могут использовать Анти-шаблон шаблона статического сервиса:

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

Ответ 3

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

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

Существует тенденция (по крайней мере некоторые) 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), проводка всех моих зависимостей в одном месте позволила нам довольно быстро и безболезненно экспериментировать с иерархиями объектов и их составом.

Ответ 4

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

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

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

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