2009-10-09 4 views
11

Из того, что я понимаю, компромисс здесь является вопросом дополнительной сложности. Может быть?Когда использовать инъекцию зависимостей? Когда не нужно?

Кажется (всегда?) Более развязанным, чтобы использовать Dependency Injection, но проще (для многих людей) без него.

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

+0

См: http://stackoverflow.com/questions/976994/when-is-using-ioc-appropriate –

+1

Не точная так как существует разница между инъекцией зависимостей и «контейнером IoC», поскольку продавцы последнего хотели бы, чтобы люди думали иначе. –

+0

[This] (http://tutorials.jenkov.com/dependency-injection/when-to-use-dependency-injection.html) статья подробно рассказывает о том, когда использовать и когда не использовать DI. –

ответ

5

Зависимость Инъекция, когда все сделано правильно (эффективно?), Безусловно, отделяет ваши объекты. На мой взгляд, область, где это преимущество реализовано больше всего, - это когда вы используете Mock или заглушки в своих модульных тестах. Довольно часто это означает, что вы будете меньше тестировать единицы в каждом отдельном тесте, делая их более простыми. Это продвижение эффективных модульных тестов тогда часто приносит свои дополнительные преимущества.

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

+0

Развязка - очень неопределенное слово для использования. Первые несколько пунктов [здесь] (https://en.wikipedia.org/wiki/Dependency_injection#Advantages) помогут вам очень хорошо, чтобы перейти к реализации. – overexchange

3

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

Например, Dependency Injection позволяет вам использовать «настоящую» базу данных или «фальшивую» базу данных, которая имитирует поведение реальной базы данных. В обоих случаях зависимость, «введенная», имеет один и тот же интерфейс, но вы можете заменить ее.

2

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

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

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

Это моя идея в любом случае.

0

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

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

Главный код:

public class A { 
    // ... 
    private service; 

    protected Service getService() { 
     return new RealService(); 
    } 

    public A() { 
     service = getService(); 
    } 
    // ... 
} 

Код испытания:

public class Test { 
    void test() { 
     final Service fakeService = new FakeService(); 
     A thingToTest = new A() { 
      protected Service getService() { return fakeService; } 
     } 
     thingToTest.doOneThing(); 
     // ... 
    } 
} 
Смежные вопросы