Является ли инъекция зависимости вручную лучшей альтернативой композиции и полиморфизму?


13

Во-первых, я программист начального уровня; На самом деле, я заканчиваю степень AS с финальным замковым проектом в течение лета. На моей новой работе, когда у меня нет какого-то проекта (они ждут, чтобы заполнить команду новыми сотрудниками), мне дали книги для чтения и обучения, пока я жду - одни учебники, другие не так много (как Code Complete). Изучив эти книги, я обратился к Интернету, чтобы узнать как можно больше, и начал изучать SOLID и DI (мы говорили о принципе замены Лискова, но не о других идеях SOLID). Итак, как я узнал, я сел для того, чтобы учиться лучше, и начал писать код для использования DI вручную (на компьютерах разработчиков нет каркасов DI).

Дело в том, что когда я это делаю, я замечаю, что это кажется знакомым ... и кажется, что это очень похоже на работу, которую я проделал в прошлом, используя композицию абстрактных классов с использованием полиморфизма. Я скучаю по большей картине здесь? Есть ли что-то в DI (по крайней мере, вручную), что выходит за рамки этого? Я понимаю возможность того, что конфигурации не будут присутствовать в коде некоторых DI-фреймворков и будут иметь некоторые большие преимущества по сравнению с изменениями без перекомпиляции, но когда я делаю это вручную, я не уверен, отличается ли это от указанных выше ... Некоторое понимание этого было бы очень полезно!

Ответы:


21

Основная идея DI заключается в том, чтобы просто помещать зависимости в объекты, а не позволять им извлекать зависимости извне. Это также называлось «инверсия контроля» ранее. Это позволяет намного лучше контролировать зависимости и, что не менее важно, писать код, который легко тестировать.

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

Чтобы определить зависимости, помимо внешних файлов конфигурации, в настоящее время также можно использовать аннотации кода, например, в таких языках, как Java и C #. Это может принести лучшее из обоих миров: связывание зависимостей в декларативном стиле, но прямо в самом коде, к которому он логически принадлежит. Для меня возможность изменения зависимостей без необходимости перекомпиляции не так важна, как это редко делается в реальной жизни (за исключением некоторых особых случаев), но вводит зачастую искусственное разделение зависимостей от классов и объектов, определенных в коде ,

Если вернуться к заглавному вопросу, DI не является альтернативой ни композиции, ни полиморфизму; в конце концов, это стало возможным благодаря этим двум.


1
Инъекция зависимости (DI) является формой инверсии контроля (IoC).
Мэтью Флинн

@ MatthewFlynn, действительно. Для справки: martinfowler.com/articles/injection.html
Петер

1
Это моя ссылка. Он рассказывает о новых «легких контейнерах», осуществляющих инверсию управления, что уже было обычным явлением, поскольку слушатели событий пользовательского интерфейса были формой IoC. Он дублирует объектную привязку, которую Spring и другие контейнеры IoC делают как Dependency Injection, чтобы отличить ее от другой формы Inversion of Control.
Мэтью Флинн

К сожалению, я пропустил "действительно". Я думал, что ты противоречишь мне ... Извините.
Мэтью Флинн

Ваш последний абзац заставляет меня чувствовать себя немного лучше; все время, пока я работал над своим маленьким учебным проектом, я продолжал говорить себе: «это похоже на полиморфизм ...». К сожалению, .Net и c # на моей работе ужасно устарели, но, глядя на это, является ли Unity встроенной средой c #, о которой вы говорите?
Дрейк Кларрис

22

Лучшая статья, которую я когда-либо читал на эту тему, была « Джеймс Шор» . Я делал " DI by Hand " целую вечность, как часть абстракции и полиморфизма. Так что после того, как я попал в профессиональный мир и продолжал слышать, как этот термин разбрасывается, у меня возникла большая разница между тем, что, по моему мнению, должно означать это слово и что оно на самом деле означает:

«Инъекция зависимости» - это понятие за 5 центов на 25 долларов.

Это из поста Шора, который все прояснил для меня. Например:

Дано

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

Вместо того чтобы писать:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

Вы напишите что-то вроде этого:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

И это не позволяет Carэкземпляру обрабатывать определенные Engineдетали. Автомобиль просто нуждается в двигателе, ему все равно, какой он реализует базовую функциональность двигателя. То есть ваш Carкласс не привязан к конкретной зависимости реализации; он «вводится» в другом месте, потенциально во время выполнения.

Этот конкретный пример Car использует подтип DI, называемый «Constructor Injection», что означает, что зависимость была передана в качестве аргумента конструктора. Вы также можете использовать setEngine(Engine a)метод для «Setter Injection» и так далее, но эти подтипы кажутся мне педантичными.

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

Вот и все.


0

Я не эксперт, так как я начал использовать DI только в последние пару лет, но некоторые полезные темы / функциональные возможности контейнеров DI, которые я заметил, (о которых я не считаю продуктами композиции / полиморфизма) (но я могу быть исправлен):

  • центральный центр создания объектов
  • предоставлять синглтоны на основе потоков
  • аспектно-ориентированные методы, такие как перехват

0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.